Compare commits

...

327 Commits

Author SHA1 Message Date
dependabot[bot]
0b03952404 build(deps): bump github/codeql-action from 3.29.7 to 4.31.2
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.29.7 to 4.31.2.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](51f77329af...0499de31b9)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-version: 4.31.2
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-01 06:16:37 +00:00
dependabot[bot]
364e273836 build(deps): bump github/codeql-action from 3.28.19 to 3.29.5 (#133)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-01 11:22:39 +02:00
dependabot[bot]
c4cde95e31 build(deps): bump step-security/harden-runner from 2.12.0 to 2.13.0 (#132)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-01 11:21:02 +02:00
Sebastian Beltran
b3cf4a76ce chore: add funding to package.json (#131) 2025-07-23 14:46:10 +02:00
dependabot[bot]
988bc1109c build(deps): bump ossf/scorecard-action from 2.4.0 to 2.4.2 (#123)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-07 12:13:38 +02:00
dependabot[bot]
411920523e build(deps): bump actions/upload-artifact from 4.5.0 to 4.6.2 (#122)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-07 12:13:06 +02:00
dependabot[bot]
068b999804 build(deps): bump coverallsapp/github-action from 1.2.5 to 2.3.6 (#121)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-07 12:12:25 +02:00
dependabot[bot]
af5eb8e7c3 build(deps): bump github/codeql-action from 3.27.9 to 3.28.19 (#124)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-07 12:11:38 +02:00
Ulises Gascón
1696289791 ci: upgrade Node versions (#128) 2025-06-07 12:06:49 +02:00
Ulises Gascón
d8efc0e652 ci: apply OSSF Scorecard security best practices (#119)
Co-authored-by: Ulises Gascón <ulisesgascongonzalez@gmail.com>
Co-authored-by: StepSecurity Bot <bot@stepsecurity.io>
2025-06-05 14:40:58 +02:00
Carlos Serrano
6729afa6d2 chore: upgrade scorecard workflow pinned action versions (#112) 2025-04-17 16:17:01 +02:00
Íñigo Marquínez Prado
544279a064 ci: migrate to GitHub actions and add missing Node.js versions (#109)
- PR-URL: https://github.com/expressjs/serve-index/pull/109
- This commit drops support for Travis
2024-05-14 18:28:45 +02:00
Íñigo Marquínez Prado
7b27f08fac chore: add support for OSSF scorecard reporting (#110)
PR-URL: https://github.com/expressjs/serve-index/pull/110
2024-05-14 18:18:01 +02:00
Douglas Christopher Wilson
d2922cd872 deps: mime-types@~2.1.30 2021-04-02 22:20:37 -04:00
Douglas Christopher Wilson
51b376a02d build: use nyc for test coverage 2021-04-01 21:41:49 -04:00
Douglas Christopher Wilson
4e7785c620 Fix icons for MIME types with "+"
fixes #99
2021-04-01 16:40:42 -04:00
Douglas Christopher Wilson
7bc2da919b build: eslint@7.23.0 2021-04-01 16:35:32 -04:00
Douglas Christopher Wilson
1e07314bb3 build: Node.js@15.13 2021-03-31 20:54:39 -04:00
Douglas Christopher Wilson
b14fff17ff build: Node.js@12.22 2021-03-31 20:48:19 -04:00
Douglas Christopher Wilson
b74579da7b build: eslint-plugin-markdown@2.0.0 2021-03-17 19:57:35 -04:00
Douglas Christopher Wilson
b827e29cc0 build: mocha@8.3.2 2021-03-17 19:44:33 -04:00
Douglas Christopher Wilson
783928d36d build: Node.js@15.11 2021-03-15 16:33:41 -04:00
Douglas Christopher Wilson
c26a84ccdb build: eslint@7.21.0 2021-02-28 00:06:53 -05:00
Douglas Christopher Wilson
6410f231d2 build: mocha@8.3.0 2021-02-27 23:48:31 -05:00
Douglas Christopher Wilson
1230f3a2a4 build: Node.js@15.10 2021-02-27 23:38:30 -05:00
Douglas Christopher Wilson
5a6402bc62 deps: mime-types@~2.1.29 2021-02-27 23:31:53 -05:00
Douglas Christopher Wilson
55c94d53d7 build: eslint@7.20.0 2021-02-25 01:24:29 -05:00
Douglas Christopher Wilson
85a41c6169 build: Node.js@10.24 2021-02-25 01:22:03 -05:00
Douglas Christopher Wilson
c22ac7619b build: Node.js@12.21 2021-02-24 20:10:12 -05:00
Douglas Christopher Wilson
410d2e0336 build: Node.js@14.16 2021-02-24 20:08:10 -05:00
Douglas Christopher Wilson
395c961e7d build: Node.js@15.8 2021-02-03 00:11:40 -05:00
Douglas Christopher Wilson
91a3cd9ac1 build: eslint@7.19.0 2021-02-02 23:51:13 -05:00
Douglas Christopher Wilson
0812a30474 build: Node.js@15.7 2021-01-27 19:36:40 -05:00
Douglas Christopher Wilson
6a3fdb0dae build: supertest@6.1.3 2021-01-27 19:33:08 -05:00
Douglas Christopher Wilson
8af3044675 build: eslint@7.17.0 2021-01-04 00:12:51 -05:00
Douglas Christopher Wilson
be96563b6b build: Node.js@15.5 2021-01-04 00:09:54 -05:00
Douglas Christopher Wilson
22828c2005 deps: mime-types@~2.1.28 2021-01-03 23:55:38 -05:00
Douglas Christopher Wilson
9c8d7e70c3 build: eslint@7.15.0 2020-12-13 23:51:58 -05:00
Douglas Christopher Wilson
ac3c870ad2 build: Node.js@15.3 2020-11-27 19:09:34 -05:00
Douglas Christopher Wilson
546b996dad build: supertest@6.0.1 2020-11-18 00:48:39 -05:00
Douglas Christopher Wilson
de3bcd39c9 build: mocha@8.2.1 2020-11-18 00:42:18 -05:00
Douglas Christopher Wilson
4bd3a75480 build: Node.js@12.20 2020-11-17 20:04:08 -05:00
Douglas Christopher Wilson
0f4a3bd370 build: eslint@7.13.0 2020-11-16 17:59:52 -05:00
Douglas Christopher Wilson
438feabf50 build: support Node.js 15.x 2020-11-07 18:44:40 -05:00
Douglas Christopher Wilson
07e47df692 build: supertest@6.0.0 2020-11-01 21:22:22 -05:00
Douglas Christopher Wilson
81afa23b29 build: Node.js@14.15 2020-10-30 22:07:21 -04:00
Douglas Christopher Wilson
cad6e104ef build: eslint@7.12.1 2020-10-29 22:09:34 -04:00
Douglas Christopher Wilson
947fc1bbc8 build: mocha@8.2.0 2020-10-27 20:41:15 -04:00
Douglas Christopher Wilson
30ae682927 build: Node.js@14.14 2020-10-24 00:32:57 -04:00
Douglas Christopher Wilson
b9469ab500 build: Node.js@10.23 2020-10-24 00:29:06 -04:00
Douglas Christopher Wilson
2fb9ab3260 build: Node.js@12.19 2020-10-23 20:21:44 -04:00
Douglas Christopher Wilson
9f931d53f9 build: eslint@7.10.0 2020-10-05 00:51:51 -04:00
Douglas Christopher Wilson
3884c54c00 build: Node.js@14.13 2020-10-04 20:01:27 -04:00
Douglas Christopher Wilson
e161893d4a build: eslint@7.8.1 2020-09-10 00:13:18 -04:00
Douglas Christopher Wilson
006327c26a build: mocha@8.1.3 2020-09-10 00:10:02 -04:00
Douglas Christopher Wilson
ed99750527 build: Node.js@14.10 2020-09-09 23:08:59 -04:00
Douglas Christopher Wilson
5f5124a79a build: eslint@7.6.0 2020-08-05 22:40:12 -04:00
Douglas Christopher Wilson
b7186ae2db build: Node.js@14.7 2020-08-03 20:16:43 -04:00
Douglas Christopher Wilson
6ed2cab63e build: mocha@8.1.0 2020-08-03 20:11:18 -04:00
Douglas Christopher Wilson
7b37172d09 build: Node.js@10.22 2020-07-18 19:44:10 -04:00
Douglas Christopher Wilson
bfef3ecf2a deps: http-errors@~1.8.0 2020-07-17 00:07:45 -04:00
Douglas Christopher Wilson
4fbef9d380 build: eslint@7.4.0 2020-07-16 20:29:49 -04:00
Douglas Christopher Wilson
c32caf8a37 build: Node.js@14.5 2020-07-16 20:25:24 -04:00
Douglas Christopher Wilson
8e68e57125 build: mocha@8.0.1 2020-06-13 22:01:34 -04:00
Douglas Christopher Wilson
f3d18ab5ce build: Node.js@12.18 2020-06-11 23:07:26 -04:00
Douglas Christopher Wilson
b7b10be97d build: Node.js@10.21 2020-06-10 19:08:41 -04:00
Douglas Christopher Wilson
d416ee987e build: eslint@7.2.0 2020-06-06 17:48:33 -04:00
Douglas Christopher Wilson
f15cbc8386 build: Node.js@14.4 2020-06-06 17:44:03 -04:00
Douglas Christopher Wilson
5c959be72f build: Node.js@12.17 2020-05-30 21:34:02 -04:00
Douglas Christopher Wilson
a92a2a10d7 build: eslint@7.1.0 2020-05-25 22:19:22 -04:00
Douglas Christopher Wilson
a4fe4bcf96 build: mocha@7.2.0 2020-05-23 19:09:35 -04:00
Douglas Christopher Wilson
fe7aa00af8 build: Node.js@14.3 2020-05-23 19:04:19 -04:00
Douglas Christopher Wilson
7e737fb9f4 build: eslint@7.0.0 2020-05-17 23:08:37 -04:00
Douglas Christopher Wilson
ba0c70c6b5 build: Node.js@14.1 2020-05-01 21:52:54 -04:00
Douglas Christopher Wilson
ee51d44121 build: mocha@7.1.2 2020-04-30 20:28:53 -04:00
Douglas Christopher Wilson
313678fdc4 build: Node.js@13.14 2020-04-29 00:08:09 -04:00
Douglas Christopher Wilson
4921806568 build: support Node.js 14.x 2020-04-28 23:11:13 -04:00
Douglas Christopher Wilson
bc57152e09 deps: mime-types@~2.1.27 2020-04-28 23:08:00 -04:00
Douglas Christopher Wilson
27facca566 build: Node.js@10.20 2020-04-20 21:58:49 -04:00
Douglas Christopher Wilson
13f7bc57a2 build: Node.js@13.13 2020-04-15 16:09:24 -04:00
Douglas Christopher Wilson
c1db68ba39 build: mocha@7.1.1 2020-04-06 17:50:45 -04:00
Douglas Christopher Wilson
cb8b5c60f4 build: eslint-plugin-markdown@1.0.2 2020-03-14 17:44:20 -04:00
Douglas Christopher Wilson
51372447e0 build: Node.js@13.10 2020-03-11 20:41:28 -04:00
Douglas Christopher Wilson
39e8b5782b build: mocha@7.1.0 2020-03-09 23:04:24 -04:00
Douglas Christopher Wilson
fc7be1bfb5 build: Node.js@12.16 2020-02-14 22:59:12 -05:00
Douglas Christopher Wilson
38768868ea build: remove deprecated Travis CI directive 2020-02-14 22:58:50 -05:00
Douglas Christopher Wilson
cd937079b3 build: Node.js@13.8 2020-02-08 20:06:33 -05:00
Douglas Christopher Wilson
4f0326af87 build: Node.js@12.15 2020-02-07 22:42:08 -05:00
Douglas Christopher Wilson
d0e883a3df build: Node.js@10.19 2020-02-07 22:41:01 -05:00
Douglas Christopher Wilson
105ca237f6 build: Node.js@13.7 2020-02-05 19:52:35 -05:00
Douglas Christopher Wilson
4d34c9b736 build: mocha@7.0.1 2020-02-05 19:51:54 -05:00
Douglas Christopher Wilson
34fffcb92c build: Node.js@13.6 2020-01-12 01:28:42 -05:00
Douglas Christopher Wilson
86e87f8c5e deps: mime-types@~2.1.26 2020-01-12 01:21:44 -05:00
Douglas Christopher Wilson
b08cbbabd4 build: mocha@7.0.0 2020-01-11 21:42:39 -05:00
Douglas Christopher Wilson
34aa14a456 build: Node.js@13.5 2019-12-24 15:27:14 -05:00
Douglas Christopher Wilson
9b69727ad2 build: eslint@6.8.0 2019-12-24 15:20:44 -05:00
Douglas Christopher Wilson
82b74e75bf build: Node.js@12.14 2019-12-19 00:28:26 -05:00
Douglas Christopher Wilson
544b6e49a2 build: Node.js@10.18 2019-12-19 00:21:13 -05:00
Douglas Christopher Wilson
84660635a2 build: Node.js@8.17 2019-12-18 21:54:37 -05:00
Douglas Christopher Wilson
8336655fcb build: Node.js@13.3 2019-12-05 18:44:26 -05:00
Douglas Christopher Wilson
6044ccbd7d build: eslint@6.7.2 2019-12-03 19:38:41 -05:00
Douglas Christopher Wilson
2f549f0bab build: Node.js@13.2 2019-11-22 00:10:20 -05:00
Douglas Christopher Wilson
87aa9ef47c deps: mime-types@~2.1.25 2019-11-21 23:39:17 -05:00
Douglas Christopher Wilson
327056b44b build: eslint-plugin-markdown@1.0.1 2019-11-19 22:54:51 -05:00
Douglas Christopher Wilson
6e1bcada54 build: Node.js@13.1 2019-11-09 20:44:00 -05:00
Douglas Christopher Wilson
4c64e7b791 build: mocha@6.2.2 2019-11-06 17:05:11 -05:00
Douglas Christopher Wilson
823d804e58 build: support Node.js 13.x 2019-11-04 19:52:20 -05:00
Douglas Christopher Wilson
8e1d258ad1 build: Node.js@12.13 2019-11-02 00:50:02 -04:00
Douglas Christopher Wilson
c24512e404 build: Node.js@10.17 2019-11-02 00:43:03 -04:00
Douglas Christopher Wilson
a15e3fbb0c build: eslint@6.6.0 2019-11-01 23:51:01 -04:00
Douglas Christopher Wilson
58bfa078c7 build: fix eslint uninstall failures 2019-09-23 00:41:20 -04:00
Douglas Christopher Wilson
9f0a8519f5 build: supertest@4.0.2 2019-09-22 23:07:53 -04:00
Douglas Christopher Wilson
214eea3175 build: Node.js@12.10 2019-09-12 21:50:06 -04:00
Douglas Christopher Wilson
018fa454e0 build: eslint@6.3.0 2019-09-10 19:45:54 -04:00
Douglas Christopher Wilson
4d8b4917e7 build: mocha@6.2.0 2019-09-10 19:40:18 -04:00
Douglas Christopher Wilson
2b82ea68fc build: Node.js@12.8 2019-08-10 16:50:24 -04:00
Douglas Christopher Wilson
3ab32ac667 build: eslint@6.1.0 2019-08-10 16:47:59 -04:00
Douglas Christopher Wilson
71b655e777 build: mocha@5.2.0 2019-08-08 23:19:32 -04:00
Douglas Christopher Wilson
2802ec6f2f build: supertest@3.4.2 2019-08-06 01:22:44 -04:00
Douglas Christopher Wilson
54e0eb7115 build: Node.js@12.7 2019-08-05 19:38:35 -04:00
Douglas Christopher Wilson
fc6d3eadac build: mocha@4.1.0 2019-07-17 19:44:53 -04:00
Douglas Christopher Wilson
e3ff991be9 build: supertest@2.0.0 2019-07-15 22:09:35 -04:00
Douglas Christopher Wilson
8fbb732bde build: mocha@3.5.3 2019-07-14 23:07:26 -04:00
Douglas Christopher Wilson
00f3ef67a6 build: restructure CI build steps 2019-07-13 21:55:53 -04:00
Douglas Christopher Wilson
5271288d1a build: eslint@5.16.0 2019-07-10 17:49:45 -04:00
Douglas Christopher Wilson
bda73e36c2 build: eslint-plugin-markdown@1.0.0 2019-07-06 18:52:56 -04:00
Douglas Christopher Wilson
9c0287c406 deps: http-errors@~1.7.3 2019-07-05 00:44:00 -04:00
Douglas Christopher Wilson
136fe69c11 build: Node.js@10.16 2019-07-05 00:27:24 -04:00
Douglas Christopher Wilson
0dde93dc69 build: Node.js@12.6 2019-07-04 23:51:06 -04:00
Douglas Christopher Wilson
12a56a6f2e build: eslint@4.19.1 2019-07-04 19:43:32 -04:00
Douglas Christopher Wilson
9569cb6852 tests: move asserts so supertest can catch 2019-06-17 20:43:06 -04:00
Douglas Christopher Wilson
20e83c893b build: support Node.js 12.x 2019-05-02 23:37:45 -04:00
Douglas Christopher Wilson
4c8c716ded build: Node.js@11.15 2019-05-02 23:37:20 -04:00
Douglas Christopher Wilson
002a251122 Fix text and json responses to match html sorting 2019-05-02 23:35:13 -04:00
Douglas Christopher Wilson
5583f9ec06 build: Node.js@11.14 2019-04-29 23:55:03 -04:00
Douglas Christopher Wilson
4482ec9639 build: Node.js@8.16 2019-04-29 23:54:49 -04:00
Douglas Christopher Wilson
e7ae813459 build: eslint-plugin-markdown@1.0.0-beta.8 2019-04-29 23:54:04 -04:00
Douglas Christopher Wilson
fa3fe02a2f deps: accepts@~1.3.7 2019-04-29 23:52:19 -04:00
Douglas Christopher Wilson
a30f269f99 deps: parseurl@~1.3.3 2019-04-28 00:56:30 -04:00
Douglas Christopher Wilson
d8ff9b9e41 deps: mime-types@~2.1.24 2019-04-28 00:55:52 -04:00
Joonas Rouhiainen
d3ee7d8f55 Use 400 error on URI decode failure instead of 500
closes #85
closes #88
2019-04-27 23:18:36 -04:00
Douglas Christopher Wilson
32b7a1adec deps: http-errors@~1.7.2 2019-04-01 00:45:20 -04:00
Douglas Christopher Wilson
173f71a6a1 deps: mime-types@~2.1.22 2019-04-01 00:38:48 -04:00
Douglas Christopher Wilson
4382b8f625 build: Node.js@11.13 2019-03-31 23:02:00 -04:00
Douglas Christopher Wilson
6636afe7fd build: Node.js@6.17 2019-03-31 22:54:48 -04:00
Douglas Christopher Wilson
156303efe0 deps: http-errors@~1.7.1 2019-01-04 21:40:16 -05:00
Douglas Christopher Wilson
9c56901718 build: support Node.js 11.x 2019-01-03 17:02:48 -05:00
Douglas Christopher Wilson
935ee09c82 build: Node.js@10.15 2018-12-30 00:14:12 -05:00
Douglas Christopher Wilson
05b0e21848 build: Node.js@8.15 2018-12-30 00:09:51 -05:00
Douglas Christopher Wilson
fadb156765 build: Node.js@6.16 2018-12-30 00:02:39 -05:00
Douglas Christopher Wilson
abedc7fcfe deps: mime-types@~2.1.21 2018-12-25 23:50:40 -05:00
Douglas Christopher Wilson
92d67676ff build: support Node.js 10.x 2018-06-09 19:26:38 -04:00
Douglas Christopher Wilson
fcad6767c0 build: Node.js@9.11 2018-06-04 00:34:22 -04:00
Douglas Christopher Wilson
9bf00b76ad deps: http-errors@~1.6.3 2018-06-04 00:21:18 -04:00
Douglas Christopher Wilson
98107736e0 deps: accepts@~1.3.5 2018-06-03 23:39:21 -04:00
Douglas Christopher Wilson
77919cf57b build: Node.js@8.11 2018-05-29 12:07:12 -04:00
Douglas Christopher Wilson
010b8c9124 build: Node.js@6.14 2018-05-26 00:08:11 -04:00
Douglas Christopher Wilson
b215084582 build: Node.js@4.9 2018-05-26 00:03:32 -04:00
Douglas Christopher Wilson
451dc90796 build: fix Node.js 0.8 appveyor build 2018-05-25 23:49:02 -04:00
Douglas Christopher Wilson
9d29665ce3 Show font icon for more font types 2018-02-21 23:24:56 -05:00
Douglas Christopher Wilson
f31db046f6 deps: mime-types@~2.1.18 2018-02-21 23:01:11 -05:00
Douglas Christopher Wilson
c67b828cbc lint: remove usages of "==" 2017-11-23 00:08:40 -05:00
Douglas Christopher Wilson
7fc9fe1f7b build: support Node.js 9.x 2017-11-23 00:02:38 -05:00
Douglas Christopher Wilson
cec35eed49 build: Node.js@8.9 2017-11-22 23:59:29 -05:00
Douglas Christopher Wilson
561f159d00 build: Node.js@6.12 2017-11-22 23:58:48 -05:00
Douglas Christopher Wilson
d66e8036f7 lint: add editorconfig and eslint to enforce 2017-11-22 23:54:40 -05:00
Douglas Christopher Wilson
b0f8f33d4a docs: remove gratipay badge 2017-11-22 23:30:04 -05:00
Douglas Christopher Wilson
a399faa180 1.9.1 2017-09-29 00:23:59 -04:00
Douglas Christopher Wilson
fc6953383f deps: parseurl@~1.3.2 2017-09-29 00:22:44 -04:00
Douglas Christopher Wilson
45dbe4f219 docs: add express.static to the express example
closes #64
2017-09-29 00:20:54 -04:00
Daniel Tschinder
76e3c3af41 deps: debug@2.6.9
closes #65
2017-09-28 23:27:29 -04:00
Douglas Christopher Wilson
da37631e2c build: Node.js@8.3 2017-09-02 20:01:11 -04:00
Douglas Christopher Wilson
3e09fb26f9 build: Node.js@6.11 2017-09-02 19:58:07 -04:00
Douglas Christopher Wilson
0894f8c9ff deps: mime-types@~2.1.17 2017-09-02 19:54:30 -04:00
Douglas Christopher Wilson
a4f1ef3d5e deps: http-errors@~1.6.2 2017-09-02 19:48:04 -04:00
Douglas Christopher Wilson
ccbeaebe69 deps: accepts@~1.3.4 2017-09-02 19:45:33 -04:00
Douglas Christopher Wilson
bc077cbe29 1.9.0 2017-05-25 15:45:44 -04:00
Douglas Christopher Wilson
9ecc9a68f9 Set X-Content-Type-Options: nosniff header 2017-05-25 01:11:36 -04:00
Douglas Christopher Wilson
2b7755a28b Refactor responding to common function 2017-05-25 01:07:35 -04:00
Douglas Christopher Wilson
506626c751 lint: remove two unused variable declarations 2017-05-25 00:51:11 -04:00
Douglas Christopher Wilson
2349675b98 build: Node.js@7.10 2017-05-25 00:45:05 -04:00
Douglas Christopher Wilson
c5a317fb45 deps: batch@0.6.1 2017-05-25 00:44:21 -04:00
Douglas Christopher Wilson
9284264604 deps: debug@2.6.8
closes #63
2017-05-25 00:42:30 -04:00
Douglas Christopher Wilson
c2585e2c16 build: Node.js@7.9 2017-04-28 22:09:36 -04:00
Douglas Christopher Wilson
e7d4062773 tests: remove unused file 2017-04-25 23:17:40 -04:00
Douglas Christopher Wilson
3e32e4ac3d build: Node.js@7.8 2017-04-25 23:13:11 -04:00
Lucian Buzzo
69137b760f deps: debug@2.6.4
closes #62
2017-04-25 23:11:41 -04:00
Douglas Christopher Wilson
a8205c834a build: Node.js@7.7 2017-03-25 22:48:16 -04:00
Douglas Christopher Wilson
d09bb5e774 deps: batch@0.6.0 2017-03-25 22:45:23 -04:00
Douglas Christopher Wilson
6024e991ca deps: debug@2.6.3 2017-03-25 22:35:02 -04:00
Douglas Christopher Wilson
f7e0bb551d deps: mime-types@~2.1.15 2017-03-25 22:32:39 -04:00
Douglas Christopher Wilson
7215f76cca build: Node.js@7.6 2017-03-08 00:17:05 -05:00
Douglas Christopher Wilson
c6b63e4666 build: Node.js@6.10 2017-03-08 00:15:37 -05:00
Douglas Christopher Wilson
ec31019c9e build: Node.js@4.8 2017-03-08 00:09:12 -05:00
Douglas Christopher Wilson
efe0c6fa7d deps: http-errors@~1.6.1 2017-03-08 00:04:36 -05:00
Douglas Christopher Wilson
d2bebdbd87 deps: mime-types@~2.1.14 2017-03-02 22:33:47 -05:00
Douglas Christopher Wilson
3048085dc4 deps: debug@2.6.1 2017-03-02 22:31:26 -05:00
Douglas Christopher Wilson
1c8c8b9a59 build: Node.js@7.4 2017-02-08 00:37:09 -05:00
Douglas Christopher Wilson
2bbaaba5cc build: Node.js@4.7 2017-02-08 00:35:08 -05:00
Douglas Christopher Wilson
84285a0826 build: support Node.js 7.x 2016-11-21 20:31:31 -05:00
Douglas Christopher Wilson
11c2b39640 deps: mime-types@~2.1.13 2016-11-21 20:30:36 -05:00
Douglas Christopher Wilson
98ecd80f57 deps: http-errors@~1.5.1 2016-11-21 20:29:37 -05:00
Douglas Christopher Wilson
53a7b06bc6 deps: debug@2.3.3 2016-11-20 22:11:16 -05:00
Douglas Christopher Wilson
4ed20255be build: Node.js@6.9 2016-11-20 22:08:36 -05:00
Douglas Christopher Wilson
8201055cba build: Node.js@4.6 2016-11-20 22:05:47 -05:00
Douglas Christopher Wilson
af6bec9cc3 docs: add preamble to install section 2016-09-15 19:16:03 +02:00
Douglas Christopher Wilson
2932faa568 build: istanbul@0.4.5 2016-09-15 19:10:35 +02:00
Douglas Christopher Wilson
dc54507b68 build: after@0.8.2 2016-09-15 19:06:24 +02:00
Douglas Christopher Wilson
72b08d6395 build: Node.js@4.5 2016-09-15 19:04:36 +02:00
Douglas Christopher Wilson
1284ad0a9f build: istanbul@0.4.4 2016-08-20 21:48:50 -04:00
Douglas Christopher Wilson
a275e385c4 build: Node.js@5.12 2016-08-20 21:43:35 -04:00
Douglas Christopher Wilson
357452911d 1.8.0 2016-06-17 12:13:08 -04:00
Douglas Christopher Wilson
fb1c509620 build: support Node.js 6.x 2016-06-16 20:37:26 -04:00
Douglas Christopher Wilson
2e1836e614 build: Node.js@5.11 2016-06-16 20:37:07 -04:00
Douglas Christopher Wilson
ed181e36ed deps: http-errors@~1.5.0 2016-06-16 19:46:25 -04:00
Douglas Christopher Wilson
f99abfe86a build: mocha@2.5.3 2016-06-16 19:44:37 -04:00
Douglas Christopher Wilson
e9ccd54a5d build: istanbul@0.4.3 2016-06-16 19:43:53 -04:00
Douglas Christopher Wilson
972e4d1ced deps: accepts@~1.3.3
fixes #56
2016-06-16 19:42:47 -04:00
Douglas Christopher Wilson
28e28c8352 deps: mime-types@~2.1.11
closes #47
2016-06-16 19:41:07 -04:00
Douglas Christopher Wilson
cd7ab38593 build: cache node_modules on CI 2016-04-17 22:19:04 -04:00
Douglas Christopher Wilson
a8c6d17b08 build: Node.js@5.10 2016-04-17 22:11:58 -04:00
Douglas Christopher Wilson
6cb3ab01a0 build: Node.js@4.4 2016-04-17 22:09:43 -04:00
Douglas Christopher Wilson
11b27ed4d3 build: mocha@2.4.5 2016-02-13 16:09:46 -05:00
Patrick Glynn
5afc181207 Make inline file search case-insensitive
closes #38
closes #45
2016-01-24 18:51:15 -05:00
Douglas Christopher Wilson
8195aa5d6a deps: accepts@~1.3.1 2016-01-24 18:45:30 -05:00
Douglas Christopher Wilson
fc9db6b56a 1.7.3 2016-01-24 18:28:28 -05:00
Douglas Christopher Wilson
ac1148a50f deps: mime-types@~2.1.9 2016-01-24 18:18:25 -05:00
Douglas Christopher Wilson
edc865cb7d deps: parseurl@~1.3.1 2016-01-24 18:17:51 -05:00
Douglas Christopher Wilson
22e7f31395 build: istanbul@0.4.2 2016-01-24 18:16:50 -05:00
Douglas Christopher Wilson
dd48453baa build: support Node.js 5.x 2016-01-03 15:18:22 -05:00
Douglas Christopher Wilson
26cc6d91c0 deps: mime-types@~2.1.8 2016-01-03 15:15:03 -05:00
Douglas Christopher Wilson
735de3e4c0 deps: escape-html@~1.0.3 2016-01-03 15:12:38 -05:00
Douglas Christopher Wilson
3ce952cfd5 deps: accepts@~1.2.13 2016-01-03 15:09:36 -05:00
Douglas Christopher Wilson
7820063014 deps: batch@0.5.3 2015-12-30 16:36:01 -05:00
Douglas Christopher Wilson
5101c6373c build: supertest@1.1.0 2015-12-30 16:28:10 -05:00
Douglas Christopher Wilson
b326b6dfa4 build: mocha@2.3.4 2015-12-30 16:25:31 -05:00
Douglas Christopher Wilson
38a1ab69fa build: istanbul@0.4.1 2015-12-30 16:19:41 -05:00
Douglas Christopher Wilson
191f4b10a3 build: support Node.js 4.x 2015-12-30 16:16:37 -05:00
Douglas Christopher Wilson
a93f8002a9 build: support io.js 3.x 2015-12-30 16:15:04 -05:00
Douglas Christopher Wilson
d3025b9744 build: io.js@2.5 2015-12-30 16:13:59 -05:00
Douglas Christopher Wilson
ac6ea7515a build: reduce runtime versions to one per major 2015-12-30 16:12:44 -05:00
Douglas Christopher Wilson
b95016be37 build: skip istanbul coverage on Node.js 0.8 2015-12-30 16:09:36 -05:00
Douglas Christopher Wilson
f39ad778ed 1.7.2 2015-07-31 00:06:52 -04:00
Douglas Christopher Wilson
73413c4caa deps: mime-types@~2.1.4 2015-07-30 23:42:56 -04:00
Douglas Christopher Wilson
6711bfa431 deps: accepts@~1.2.12 2015-07-30 23:42:19 -04:00
Douglas Christopher Wilson
f17363a45d 1.7.1 2015-07-05 23:32:34 -04:00
Douglas Christopher Wilson
db2163892e deps: mime-types@~2.1.2 2015-07-05 23:30:07 -04:00
Douglas Christopher Wilson
5c74d1e44a deps: accepts@~1.2.10 2015-07-05 23:29:30 -04:00
Douglas Christopher Wilson
bd6f5553a5 build: io.js@2.3 2015-07-05 23:28:22 -04:00
Douglas Christopher Wilson
63b45e6208 1.7.0 2015-06-15 16:50:22 -04:00
Douglas Christopher Wilson
d680e6302d Accept function value for template option
closes #20
closes #30
2015-06-14 23:07:52 -04:00
Douglas Christopher Wilson
420d159be7 Stat parent directory when necessary 2015-06-14 22:29:58 -04:00
Douglas Christopher Wilson
6d3160a32c Use Date.prototype.toLocaleDateString to format date 2015-06-14 22:01:22 -04:00
Douglas Christopher Wilson
4056d3375c deps: mime-types@~2.1.1 2015-06-14 21:17:01 -04:00
Douglas Christopher Wilson
7566e487b0 deps: accepts@~1.2.9 2015-06-14 21:14:45 -04:00
Douglas Christopher Wilson
3ae1ea56d3 perf: remove argument reassignment 2015-06-14 21:13:27 -04:00
Douglas Christopher Wilson
d60c7a0055 Send non-chunked response for OPTIONS 2015-06-14 21:01:42 -04:00
Douglas Christopher Wilson
6781d9536b perf: enable strict mode 2015-06-14 21:00:45 -04:00
Douglas Christopher Wilson
ea919ec568 deps: escape-html@1.0.2 2015-06-14 20:59:38 -04:00
Douglas Christopher Wilson
07611f42ad build: supertest@1.0.1 2015-06-14 20:56:13 -04:00
Douglas Christopher Wilson
e4355f0e97 build: mocha@2.2.5 2015-06-14 20:55:24 -04:00
Douglas Christopher Wilson
5275b835a7 build: io.js@2.1 2015-06-14 20:54:28 -04:00
Douglas Christopher Wilson
636a8ae7bc 1.6.4 2015-05-12 21:28:44 -04:00
Douglas Christopher Wilson
320226f35a deps: mime-types@~2.0.11 2015-05-12 21:00:31 -04:00
Douglas Christopher Wilson
2003c3f743 deps: mocha@~2.2.4 2015-05-12 20:59:49 -04:00
Douglas Christopher Wilson
e385089155 deps: debug@~2.2.0 2015-05-12 20:59:15 -04:00
Douglas Christopher Wilson
5462db3946 deps: accepts@~1.2.7 2015-05-12 20:58:24 -04:00
Douglas Christopher Wilson
cb60444cb1 deps: istanbul@0.3.9 2015-05-12 20:57:39 -04:00
Douglas Christopher Wilson
6691f1b75e build: support io.js 2.x 2015-05-12 14:46:31 -04:00
Douglas Christopher Wilson
5cb8bcc448 build: io.js@1.8 2015-05-12 13:14:15 -04:00
Douglas Christopher Wilson
e11f253226 1.6.3 2015-03-14 01:22:30 -04:00
Douglas Christopher Wilson
7381a1d145 Properly escape file names in HTML
fixes #28
2015-03-13 22:34:00 -04:00
Douglas Christopher Wilson
6a4a87edcd build: support io.js 1.x 2015-03-13 22:25:52 -04:00
Douglas Christopher Wilson
99e8ec512a deps: mime-types@~2.0.10 2015-03-13 22:24:20 -04:00
Douglas Christopher Wilson
197d9f6a0f deps: accepts@~1.2.5 2015-03-13 22:23:39 -04:00
Douglas Christopher Wilson
41fe20602a deps: debug@~2.1.3 2015-03-13 21:33:11 -04:00
Douglas Christopher Wilson
b5c886f36d deps: mocha@~2.2.1 2015-03-12 19:03:04 -04:00
Douglas Christopher Wilson
6da896f6d8 deps: istanbul@0.3.7 2015-03-11 22:43:09 -04:00
Douglas Christopher Wilson
5ec9698c08 1.6.2 2015-02-16 22:50:32 -05:00
Douglas Christopher Wilson
4da905e4d3 deps: http-errors@~1.3.1 2015-02-16 19:50:16 -05:00
Douglas Christopher Wilson
62ac6f345b deps: mime-types@~2.0.9 2015-02-16 19:49:09 -05:00
Douglas Christopher Wilson
9afe1a7816 deps: accepts@~1.2.4 2015-02-16 19:48:10 -05:00
Douglas Christopher Wilson
0368c20a58 docs: update badges 2015-02-16 19:46:45 -05:00
Douglas Christopher Wilson
66a13d0814 build: support Node.js 0.12 2015-02-16 19:45:12 -05:00
Douglas Christopher Wilson
b8d8f4524e build: use Travis CI container infrastructure 2015-02-16 19:44:34 -05:00
Douglas Christopher Wilson
75efc2d68e build: use faster AppVeyor Node.js switching 2015-02-16 19:44:04 -05:00
Douglas Christopher Wilson
0bdab07acf 1.6.1 2015-02-01 02:51:12 -05:00
Douglas Christopher Wilson
a6f02f060d build: add AppVeyor 2015-02-01 02:43:24 -05:00
Douglas Christopher Wilson
90252c37b9 deps: accepts@~1.2.3 2015-02-01 02:34:57 -05:00
Douglas Christopher Wilson
94fcb7092e deps: mime-types@~2.0.8 2015-02-01 02:34:03 -05:00
Douglas Christopher Wilson
803e4154b2 1.6.0 2015-01-01 22:15:51 -05:00
Douglas Christopher Wilson
267913151b deps: accepts@~1.2.2 2015-01-01 22:07:12 -05:00
Douglas Christopher Wilson
b1e36ccbf5 deps: batch@0.5.2 2015-01-01 22:05:06 -05:00
Douglas Christopher Wilson
55e914660b deps: mocha@~2.1.0 2015-01-01 21:54:23 -05:00
Douglas Christopher Wilson
0ff43c75a8 deps: mime-types@~2.0.7 2015-01-01 21:53:37 -05:00
Douglas Christopher Wilson
d15b5f1387 deps: debug@~2.1.1 2015-01-01 21:52:27 -05:00
Douglas Christopher Wilson
d5a4b93449 Add link to root directory
closes #23
2014-12-10 23:40:44 -05:00
Douglas Christopher Wilson
244f8a5541 1.5.3 2014-12-10 22:41:49 -05:00
Douglas Christopher Wilson
ed11812d3f deps: http-errors@~1.2.8 2014-12-10 22:40:54 -05:00
Douglas Christopher Wilson
4881fb27da deps: mime-types@~2.0.4 2014-12-10 22:40:20 -05:00
Douglas Christopher Wilson
07e47b1e78 deps: accepts@~1.1.4 2014-12-10 22:39:42 -05:00
Douglas Christopher Wilson
55a5939596 deps: istanbul@0.3.5 2014-12-10 22:38:21 -05:00
Douglas Christopher Wilson
12d7cb4a7d 1.5.2 2014-12-03 16:32:59 -05:00
Douglas Christopher Wilson
c602a95d4c deps: istanbul@0.3.3 2014-12-03 16:30:33 -05:00
李文富
bf15ad0e12 Fix icon name background alignment on mobile view
closes #25
2014-11-28 12:13:09 -05:00
Douglas Christopher Wilson
9a77df8c77 1.5.1 2014-11-22 23:21:30 -05:00
Douglas Christopher Wilson
856450da8f tests: use assert instead of should 2014-11-22 23:01:45 -05:00
Douglas Christopher Wilson
1bda9f95e4 deps: supertest@~0.15.0 2014-11-22 22:26:12 -05:00
Douglas Christopher Wilson
f0652de409 deps: mocha@~2.0.1 2014-11-22 22:25:24 -05:00
Douglas Christopher Wilson
f0579f7093 deps: mime-types@~2.0.3 2014-11-22 22:24:52 -05:00
Douglas Christopher Wilson
970b567f48 deps: accepts@~1.1.3 2014-11-22 22:22:37 -05:00
Douglas Christopher Wilson
47b3884bbe 1.5.0 2014-10-17 01:31:52 -04:00
Douglas Christopher Wilson
5b2ff74554 Create errors with http-errors 2014-10-16 23:16:04 -04:00
Douglas Christopher Wilson
7dc0ff4d97 deps: debug@~2.1.0 2014-10-16 23:10:10 -04:00
Douglas Christopher Wilson
1bdd53c05d deps: mime-types@~2.0.2 2014-10-16 23:08:47 -04:00
Douglas Christopher Wilson
dce12186f8 docs: Gittip is now Gratipay 2014-10-16 23:07:23 -04:00
Douglas Christopher Wilson
838ee4cc02 1.4.1 2014-10-15 23:22:23 -04:00
Douglas Christopher Wilson
f332e6e576 deps: accepts@~1.1.2 2014-10-15 23:21:53 -04:00
Douglas Christopher Wilson
b866f9690a deps: mocha@~1.21.5 2014-10-15 23:20:50 -04:00
Douglas Christopher Wilson
ac94303941 1.4.0 2014-10-03 12:02:53 -04:00
Evgenus
cececc8c2e Add dir argument to filter function
fixes #11
closes #18
2014-10-03 11:45:59 -04:00
Evgenus
5e050a7d23 Support using tokens multiple times
closes #19
2014-10-03 11:17:30 -04:00
Douglas Christopher Wilson
5731ebee6b 1.3.1 2014-10-01 11:36:15 -04:00
Douglas Christopher Wilson
c6b9d3bdbf docs: fix non-https badge 2014-10-01 11:29:54 -04:00
Douglas Christopher Wilson
4686c18e1d deps: supertest@~0.14.0 2014-10-01 11:07:38 -04:00
Douglas Christopher Wilson
8a06bb7e19 deps: accepts@~1.1.1 2014-10-01 11:05:24 -04:00
Douglas Christopher Wilson
effbe1a4b0 Fix incorrect 403 on Windows and Node.js 0.11
fixes #17
2014-10-01 11:05:11 -04:00
24 changed files with 1612 additions and 463 deletions

11
.editorconfig Normal file
View File

@@ -0,0 +1,11 @@
# http://editorconfig.org
root = true
[*]
charset = utf-8
insert_final_newline = true
trim_trailing_whitespace = true
[{*.js,*.json,*.yml}]
indent_size = 2
indent_style = space

3
.eslintignore Normal file
View File

@@ -0,0 +1,3 @@
.nyc_output
coverage
node_modules

13
.eslintrc.yml Normal file
View File

@@ -0,0 +1,13 @@
root: true
extends:
- plugin:markdown/recommended
plugins:
- markdown
overrides:
- files: '**/*.md'
processor: 'markdown/markdown'
rules:
eol-last: error
eqeqeq: [error, allow-null]
indent: [error, 2, { SwitchCase: 1 }]
no-trailing-spaces: error

15
.github/dependabot.yml vendored Normal file
View File

@@ -0,0 +1,15 @@
version: 2
updates:
- package-ecosystem: github-actions
directory: /
schedule:
interval: monthly
- package-ecosystem: npm
directory: /
schedule:
interval: monthly
open-pull-requests-limit: 10
ignore:
- dependency-name: "*"
update-types: ["version-update:semver-major"]

241
.github/workflows/ci.yml vendored Normal file
View File

@@ -0,0 +1,241 @@
name: ci
on:
- pull_request
- push
permissions:
contents: read
jobs:
test:
permissions:
checks: write # for coverallsapp/github-action to create new checks
contents: read # for actions/checkout to fetch code
runs-on: ubuntu-latest
strategy:
matrix:
name:
- Node.js 0.8
- Node.js 0.10
- Node.js 0.12
- io.js 1.x
- io.js 2.x
- io.js 3.x
- Node.js 4.x
- Node.js 5.x
- Node.js 6.x
- Node.js 7.x
- Node.js 8.x
- Node.js 9.x
- Node.js 10.x
- Node.js 11.x
- Node.js 12.x
- Node.js 13.x
- Node.js 14.x
- Node.js 15.x
- Node.js 16.x
- Node.js 17.x
- Node.js 18.x
- Node.js 19.x
- Node.js 20.x
- Node.js 21.x
- Node.js 22.x
- Node.js 23.x
- Node.js 24.x
include:
- name: Node.js 0.8
node-version: "0.8"
npm-i: mocha@2.5.3 supertest@1.1.0
npm-rm: nyc
- name: Node.js 0.10
node-version: "0.10"
npm-i: mocha@3.5.3 nyc@10.3.2 supertest@2.0.1
- name: Node.js 0.12
node-version: "0.12"
npm-i: mocha@3.5.3 nyc@10.3.2 supertest@2.0.1
- name: io.js 1.x
node-version: "1"
npm-i: mocha@3.5.3 nyc@10.3.2 supertest@2.0.1
- name: io.js 2.x
node-version: "2"
npm-i: mocha@3.5.3 nyc@10.3.2 supertest@2.0.1
- name: io.js 3.x
node-version: "3"
npm-i: mocha@3.5.3 nyc@10.3.2 supertest@2.0.1
- name: Node.js 4.x
node-version: "4"
npm-i: mocha@5.2.0 nyc@11.9.0 supertest@3.4.2
- name: Node.js 5.x
node-version: "5"
npm-i: mocha@5.2.0 nyc@11.9.0 supertest@3.4.2
- name: Node.js 6.x
node-version: "6"
npm-i: mocha@6.2.2 nyc@14.1.1 supertest@6.1.3
- name: Node.js 7.x
node-version: "7"
npm-i: mocha@6.2.2 nyc@14.1.1 supertest@6.1.3
- name: Node.js 8.x
node-version: "8"
npm-i: mocha@7.1.2 nyc@14.1.1 supertest@6.1.3
- name: Node.js 9.x
node-version: "9"
npm-i: mocha@7.1.2 nyc@14.1.1 supertest@6.1.3
- name: Node.js 10.x
node-version: "10"
npm-i: mocha@8.4.0 supertest@6.1.3
- name: Node.js 11.x
node-version: "11"
npm-i: mocha@8.4.0 supertest@6.1.3
- name: Node.js 12.x
node-version: "12"
npm-i: mocha@9.2.2 supertest@6.1.3
- name: Node.js 13.x
node-version: "13"
npm-i: mocha@9.2.2 supertest@6.1.3
- name: Node.js 14.x
node-version: "14"
npm-i: supertest@6.1.3
- name: Node.js 15.x
node-version: "15"
npm-i: supertest@6.1.3
- name: Node.js 16.x
node-version: "16"
npm-i: supertest@6.1.3
- name: Node.js 17.x
node-version: "17"
npm-i: supertest@6.1.3
- name: Node.js 18.x
node-version: "18"
- name: Node.js 19.x
node-version: "19"
- name: Node.js 20.x
node-version: "20"
- name: Node.js 21.x
node-version: "21"
- name: Node.js 22.x
node-version: "22"
- name: Node.js 23.x
node-version: "23"
- name: Node.js 24.x
node-version: "24"
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Install Node.js ${{ matrix.node-version }}
shell: bash -eo pipefail -l {0}
run: |
nvm install --default ${{ matrix.node-version }}
if [[ "${{ matrix.node-version }}" == 0.* && "$(cut -d. -f2 <<< "${{ matrix.node-version }}")" -lt 10 ]]; then
nvm install --alias=npm 0.10
nvm use ${{ matrix.node-version }}
if [[ "$(npm -v)" == 1.1.* ]]; then
nvm exec npm npm install -g npm@1.1
ln -fs "$(which npm)" "$(dirname "$(nvm which npm)")/npm"
else
sed -i '1s;^.*$;'"$(printf '#!%q' "$(nvm which npm)")"';' "$(readlink -f "$(which npm)")"
fi
npm config set strict-ssl false
fi
dirname "$(nvm which ${{ matrix.node-version }})" >> "$GITHUB_PATH"
- name: Configure npm
run: |
if [[ "$(npm config get package-lock)" == "true" ]]; then
npm config set package-lock false
else
npm config set shrinkwrap false
fi
- name: Remove npm module(s) ${{ matrix.npm-rm }}
if: matrix.npm-rm != ''
run: npm rm --silent --save-dev ${{ matrix.npm-rm }}
- name: Install npm module(s) ${{ matrix.npm-i }}
if: matrix.npm-i != ''
run: npm install --save-dev ${{ matrix.npm-i }}
- name: Setup Node.js version-specific dependencies
shell: bash
run: |
# eslint for linting
# - remove on Node.js < 12
if [[ "$(cut -d. -f1 <<< "${{ matrix.node-version }}")" -lt 12 ]]; then
node -pe 'Object.keys(require("./package").devDependencies).join("\n")' | \
grep -E '^eslint(-|$)' | \
sort -r | \
xargs -n1 npm rm --silent --save-dev
fi
- name: Install Node.js dependencies
run: npm install
- name: List environment
id: list_env
shell: bash
run: |
echo "node@$(node -v)"
echo "npm@$(npm -v)"
npm -s ls ||:
(npm -s ls --depth=0 ||:) | awk -F'[ @]' 'NR>1 && $2 { print $2 "=" $3 }' >> "$GITHUB_OUTPUT"
- name: Run tests
shell: bash
run: |
if npm -ps ls nyc | grep -q nyc; then
npm run test-ci
else
npm test
fi
- name: Lint code
if: steps.list_env.outputs.eslint != ''
run: npm run lint
- name: Collect code coverage
uses: coverallsapp/github-action@648a8eb78e6d50909eff900e4ec85cab4524a45b # master
if: steps.list_env.outputs.nyc != ''
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
flag-name: run-${{ matrix.test_number }}
parallel: true
coverage:
permissions:
checks: write # for coverallsapp/github-action to create new checks
needs: test
runs-on: ubuntu-latest
steps:
- name: Upload code coverage
uses: coverallsapp/github-action@648a8eb78e6d50909eff900e4ec85cab4524a45b # master
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
parallel-finished: true

78
.github/workflows/codeql.yml vendored Normal file
View File

@@ -0,0 +1,78 @@
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL"
on:
push:
branches: ["master"]
pull_request:
# The branches below must be a subset of the branches above
branches: ["master"]
schedule:
- cron: "0 0 * * 1"
permissions:
contents: read
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
language: ["javascript"]
# CodeQL supports [ $supported-codeql-languages ]
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
steps:
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
with:
egress-policy: audit
- name: Checkout repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@0499de31b99561a6d14a36a5f662c2a54f91beee # v3.29.5
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@0499de31b99561a6d14a36a5f662c2a54f91beee # v3.29.5
# Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
# If the Autobuild fails above, remove it and uncomment the following three lines.
# modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
# - run: |
# echo "Run, Build Application using script"
# ./location_of_script_within_repo/buildscript.sh
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@0499de31b99561a6d14a36a5f662c2a54f91beee # v3.29.5
with:
category: "/language:${{matrix.language}}"

73
.github/workflows/scorecard.yml vendored Normal file
View File

@@ -0,0 +1,73 @@
# This workflow uses actions that are not certified by GitHub. They are provided
# by a third-party and are governed by separate terms of service, privacy
# policy, and support documentation.
name: Scorecard supply-chain security
on:
# For Branch-Protection check. Only the default branch is supported. See
# https://github.com/ossf/scorecard/blob/main/docs/checks.md#branch-protection
branch_protection_rule:
# To guarantee Maintained check is occasionally updated. See
# https://github.com/ossf/scorecard/blob/main/docs/checks.md#maintained
schedule:
- cron: '16 21 * * 1'
push:
branches: [ "master" ]
# Declare default permissions as read only.
permissions: read-all
jobs:
analysis:
name: Scorecard analysis
runs-on: ubuntu-latest
permissions:
# Needed to upload the results to code-scanning dashboard.
security-events: write
# Needed to publish results and get a badge (see publish_results below).
id-token: write
# Uncomment the permissions below if installing in a private repository.
# contents: read
# actions: read
steps:
- name: "Checkout code"
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
persist-credentials: false
- name: "Run analysis"
uses: ossf/scorecard-action@05b42c624433fc40578a4040d5cf5e36ddca8cde # v2.4.2
with:
results_file: results.sarif
results_format: sarif
# (Optional) "write" PAT token. Uncomment the `repo_token` line below if:
# - you want to enable the Branch-Protection check on a *public* repository, or
# - you are installing Scorecard on a *private* repository
# To create the PAT, follow the steps in https://github.com/ossf/scorecard-action#authentication-with-pat.
# repo_token: ${{ secrets.SCORECARD_TOKEN }}
# Public repositories:
# - Publish results to OpenSSF REST API for easy access by consumers
# - Allows the repository to include the Scorecard badge.
# - See https://github.com/ossf/scorecard-action#publishing-results.
# For private repositories:
# - `publish_results` will always be set to `false`, regardless
# of the value entered here.
publish_results: true
# Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
# format to the repository Actions tab.
- name: "Upload artifact"
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: SARIF file
path: results.sarif
retention-days: 5
# Upload the results to GitHub's code scanning dashboard.
- name: "Upload to code-scanning"
uses: github/codeql-action/upload-sarif@0499de31b99561a6d14a36a5f662c2a54f91beee # v3.29.5
with:
sarif_file: results.sarif

2
.gitignore vendored
View File

@@ -1,3 +1,5 @@
.nyc_output/
coverage
node_modules
npm-debug.log
package-lock.json

View File

@@ -1,11 +0,0 @@
language: node_js
node_js:
- "0.8"
- "0.10"
- "0.11"
matrix:
allow_failures:
- node_js: "0.11"
fast_finish: true
script: "npm run-script test-travis"
after_script: "npm install coveralls@2.10.0 && cat ./coverage/lcov.info | coveralls"

View File

@@ -1,3 +1,248 @@
unreleased
==========
* Fix icons for MIME types with `+`
* Fix text and json responses to match html sorting
* Show font icon for more font types
* Use 400 error on URI decode failure instead of 500
* deps: accepts@~1.3.7
- deps: mime-types@~2.1.24
- deps: negotiator@0.6.2
* deps: http-errors@~1.8.0
- Set constructor name when possible
- deps: depd@~1.1.2
- deps: inherits@2.0.4
- deps: setprototypeof@1.2.0
- deps: statuses@'>= 1.5.0 < 2'
* deps: mime-types@~2.1.30
- Add new mime types
- deps: mime-db@~1.47.0
* deps: parseurl@~1.3.3
1.9.1 / 2017-09-28
==================
* deps: accepts@~1.3.4
- deps: mime-types@~2.1.16
* deps: debug@2.6.9
* deps: http-errors@~1.6.2
- deps: depd@1.1.1
* deps: mime-types@~2.1.17
- Add new mime types
- deps: mime-db@~1.30.0
* deps: parseurl@~1.3.2
- perf: reduce overhead for full URLs
- perf: unroll the "fast-path" `RegExp`
1.9.0 / 2017-05-25
==================
* Set `X-Content-Type-Options: nosniff` header
* deps: batch@0.6.1
* deps: debug@2.6.8
- Allow colors in workers
- Deprecated `DEBUG_FD` environment variable set to `3` or higher
- Fix `DEBUG_MAX_ARRAY_LENGTH`
- Fix error when running under React Native
- Use same color for same namespace
- deps: ms@2.0.0
* deps: http-errors@~1.6.1
- Make `message` property enumerable for `HttpError`s
- deps: inherits@2.0.3
- deps: setprototypeof@1.0.3
- deps: statuses@'>= 1.3.1 < 2'
* deps: mime-types@~2.1.15
- Add new mime types
- Add `audio/mp3`
1.8.0 / 2016-06-17
==================
* Make inline file search case-insensitive
* deps: accepts@~1.3.3
- deps: mime-types@~2.1.11
- deps: negotiator@0.6.1
- perf: improve header parsing speed
* deps: http-errors@~1.5.0
- Use `setprototypeof` module to replace `__proto__` setting
- deps: inherits@2.0.1
- deps: statuses@'>= 1.3.0 < 2'
- perf: enable strict mode
* deps: mime-types@~2.1.11
- Add new mime types
- Update primary extension for `audio/mp4`
- deps: mime-db@~1.23.0
1.7.3 / 2016-01-24
==================
* deps: accepts@~1.2.13
- deps: mime-types@~2.1.6
* deps: batch@0.5.3
- Fix invalid dependency for browserify
* deps: escape-html@~1.0.3
- perf: enable strict mode
- perf: optimize string replacement
- perf: use faster string coercion
* deps: mime-types@~2.1.9
- Add new mime types
* deps: parseurl@~1.3.1
- perf: enable strict mode
1.7.2 / 2015-07-30
==================
* deps: accepts@~1.2.12
- deps: mime-types@~2.1.4
* deps: mime-types@~2.1.4
- Add new mime types
1.7.1 / 2015-07-05
==================
* deps: accepts@~1.2.10
- deps: mime-types@~2.1.2
* deps: mime-types@~2.1.2
- Add new mime types
1.7.0 / 2015-06-15
==================
* Accept `function` value for `template` option
* Send non-chunked response for `OPTIONS`
* Stat parent directory when necessary
* Use `Date.prototype.toLocaleDateString` to format date
* deps: accepts@~1.2.9
- deps: mime-types@~2.1.1
- deps: negotiator@0.5.3
- perf: avoid argument reassignment & argument slice
- perf: avoid negotiator recursive construction
- perf: enable strict mode
- perf: remove unnecessary bitwise operator
* deps: escape-html@1.0.2
* deps: mime-types@~2.1.1
- Add new mime types
* perf: enable strict mode
* perf: remove argument reassignment
1.6.4 / 2015-05-12
==================
* deps: accepts@~1.2.7
- deps: mime-types@~2.0.11
- deps: negotiator@0.5.3
* deps: debug@~2.2.0
- deps: ms@0.7.1
* deps: mime-types@~2.0.11
- Add new mime types
1.6.3 / 2015-03-13
==================
* Properly escape file names in HTML
* deps: accepts@~1.2.5
- deps: mime-types@~2.0.10
* deps: debug@~2.1.3
- Fix high intensity foreground color for bold
- deps: ms@0.7.0
* deps: escape-html@1.0.1
* deps: mime-types@~2.0.10
- Add new mime types
1.6.2 / 2015-02-16
==================
* deps: accepts@~1.2.4
- deps: mime-types@~2.0.9
- deps: negotiator@0.5.1
* deps: http-errors@~1.3.1
- Construct errors using defined constructors from `createError`
- Fix error names that are not identifiers
- Set a meaningful `name` property on constructed errors
* deps: mime-types@~2.0.9
- Add new mime types
- deps: mime-db@~1.7.0
1.6.1 / 2015-01-31
==================
* deps: accepts@~1.2.3
- deps: mime-types@~2.0.8
* deps: mime-types@~2.0.8
- Add new mime types
- deps: mime-db@~1.6.0
1.6.0 / 2015-01-01
==================
* Add link to root directory
* deps: accepts@~1.2.2
- deps: mime-types@~2.0.7
- deps: negotiator@0.5.0
* deps: batch@0.5.2
* deps: debug@~2.1.1
* deps: mime-types@~2.0.7
- Add new mime types
- Fix missing extensions
- Fix various invalid MIME type entries
- Remove example template MIME types
- deps: mime-db@~1.5.0
1.5.3 / 2014-12-10
==================
* deps: accepts@~1.1.4
- deps: mime-types@~2.0.4
* deps: http-errors@~1.2.8
- Fix stack trace from exported function
* deps: mime-types@~2.0.4
- Add new mime types
- deps: mime-db@~1.3.0
1.5.2 / 2014-12-03
==================
* Fix icon name background alignment on mobile view
1.5.1 / 2014-11-22
==================
* deps: accepts@~1.1.3
- deps: mime-types@~2.0.3
* deps: mime-types@~2.0.3
- Add new mime types
- deps: mime-db@~1.2.0
1.5.0 / 2014-10-16
==================
* Create errors with `http-errors`
* deps: debug@~2.1.0
- Implement `DEBUG_FD` env variable support
* deps: mime-types@~2.0.2
- deps: mime-db@~1.1.0
1.4.1 / 2014-10-15
==================
* deps: accepts@~1.1.2
- Fix error when media type has invalid parameter
- deps: negotiator@0.4.9
1.4.0 / 2014-10-03
==================
* Add `dir` argument to `filter` function
* Support using tokens multiple times
1.3.1 / 2014-10-01
==================
* Fix incorrect 403 on Windows and Node.js 0.11
* deps: accepts@~1.1.1
- deps: mime-types@~2.0.2
- deps: negotiator@0.4.8
1.3.0 / 2014-09-20
==================

View File

@@ -3,7 +3,7 @@
Copyright (c) 2010 Sencha Inc.
Copyright (c) 2011 LearnBoost
Copyright (c) 2011 TJ Holowaychuk
Copyright (c) 2014 Douglas Christopher Wilson
Copyright (c) 2014-2015 Douglas Christopher Wilson
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the

View File

@@ -2,14 +2,18 @@
[![NPM Version][npm-image]][npm-url]
[![NPM Downloads][downloads-image]][downloads-url]
[![Build Status][travis-image]][travis-url]
[![Test Coverage][coveralls-image]][coveralls-url]
[![Gittip][gittip-image]][gittip-url]
[![Linux Build Status][ci-image]][ci-url]
[![Windows Build][appveyor-image]][appveyor-url]
[![Coverage Status][coveralls-image]][coveralls-url]
Serves pages that contain directory listings for a given path.
## Install
This is a [Node.js](https://nodejs.org/en/) module available through the
[npm registry](https://www.npmjs.com/). Installation is done using the
[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
```sh
$ npm install serve-index
```
@@ -35,7 +39,11 @@ Serve index accepts these properties in the options object.
##### filter
Apply this filter function to files. Defaults to `false`.
Apply this filter function to files. Defaults to `false`. The `filter` function
is called for each file, with the signature `filter(filename, index, files, dir)`
where `filename` is the name of the file, `index` is the array index, `files` is
the array of files and `dir` is the absolute path the file is located (and thus,
the directory the listing is for).
##### hidden
@@ -51,15 +59,31 @@ Optional path to a CSS stylesheet. Defaults to a built-in stylesheet.
##### template
Optional path to an HTML template. Defaults to a built-in template.
Optional path to an HTML template or a function that will render a HTML
string. Defaults to a built-in template.
The following tokens are replaced in templates:
When given a string, the string is used as a file path to load and then the
following tokens are replaced in templates:
* `{directory}` with the name of the directory.
* `{files}` with the HTML of an unordered list of file links.
* `{linked-path}` with the HTML of a link to the directory.
* `{style}` with the specified stylesheet and embedded images.
When given as a function, the function is called as `template(locals, callback)`
and it needs to invoke `callback(error, htmlString)`. The following are the
provided locals:
* `directory` is the directory being displayed (where `/` is the root).
* `displayIcons` is a Boolean for if icons should be rendered or not.
* `fileList` is a sorted array of files in the directory. The array contains
objects with the following properties:
- `name` is the relative name for the file.
- `stat` is a `fs.Stats` object for the file.
* `path` is the full filesystem path to `directory`.
* `style` is the default stylesheet or the contents of the `stylesheet` option.
* `viewName` is the view name provided by the `view` option.
##### view
Display mode. `tiles` and `details` are available. Defaults to `tiles`.
@@ -102,8 +126,12 @@ var serveIndex = require('serve-index')
var app = express()
// Serve URLs like /ftp/thing as public/ftp/thing
app.use('/ftp', serveIndex('public/ftp', {'icons': true}))
app.listen()
// The express.static serves the file contents
// The serveIndex is this module serving the directory
app.use('/ftp', express.static('public/ftp'), serveIndex('public/ftp', {'icons': true}))
// Listen
app.listen(3000)
```
## License
@@ -111,13 +139,13 @@ app.listen()
[MIT](LICENSE). The [Silk](http://www.famfamfam.com/lab/icons/silk/) icons
are created by/copyright of [FAMFAMFAM](http://www.famfamfam.com/).
[npm-image]: https://img.shields.io/npm/v/serve-index.svg?style=flat
[npm-url]: https://npmjs.org/package/serve-index
[travis-image]: https://img.shields.io/travis/expressjs/serve-index.svg?style=flat
[travis-url]: https://travis-ci.org/expressjs/serve-index
[coveralls-image]: https://img.shields.io/coveralls/expressjs/serve-index.svg?style=flat
[appveyor-image]: https://img.shields.io/appveyor/ci/dougwilson/serve-index/master.svg?label=windows
[appveyor-url]: https://ci.appveyor.com/project/dougwilson/serve-index
[ci-image]: https://badgen.net/github/checks/expressjs/serve-index/master?label=ci
[ci-url]: https://github.com/expressjs/serve-index/actions/workflows/ci.yml
[coveralls-image]: https://img.shields.io/coveralls/expressjs/serve-index/master.svg
[coveralls-url]: https://coveralls.io/r/expressjs/serve-index?branch=master
[downloads-image]: http://img.shields.io/npm/dm/serve-index.svg?style=flat
[downloads-image]: https://img.shields.io/npm/dm/serve-index.svg
[downloads-url]: https://npmjs.org/package/serve-index
[gittip-image]: https://img.shields.io/gittip/dougwilson.svg?style=flat
[gittip-url]: https://www.gittip.com/dougwilson/
[npm-image]: https://img.shields.io/npm/v/serve-index.svg
[npm-url]: https://npmjs.org/package/serve-index

92
appveyor.yml Normal file
View File

@@ -0,0 +1,92 @@
environment:
matrix:
- nodejs_version: "0.8"
- nodejs_version: "0.10"
- nodejs_version: "0.12"
- nodejs_version: "1.8"
- nodejs_version: "2.5"
- nodejs_version: "3.3"
- nodejs_version: "4.9"
- nodejs_version: "5.12"
- nodejs_version: "6.17"
- nodejs_version: "7.10"
- nodejs_version: "8.17"
- nodejs_version: "9.11"
- nodejs_version: "10.24"
- nodejs_version: "11.15"
- nodejs_version: "12.22"
- nodejs_version: "13.14"
- nodejs_version: "14.16"
- nodejs_version: "15.13"
cache:
- node_modules
install:
# Install Node.js
- ps: >-
try { Install-Product node $env:nodejs_version -ErrorAction Stop }
catch { Update-NodeJsInstallation (Get-NodeJsLatestBuild $env:nodejs_version) }
# Configure npm
- ps: |
# Skip updating shrinkwrap / lock
npm config set shrinkwrap false
# Skip SSL validation on Node.js < 0.10
if ([int]$env:nodejs_version.split(".")[0] -eq 0 -and [int]$env:nodejs_version.split(".")[1] -lt 10) {
npm config set strict-ssl false
}
# Remove all non-test dependencies
- ps: |
# Remove coverage dependency
npm rm --silent --save-dev nyc
# Remove lint dependencies
cmd.exe /c "node -pe `"Object.keys(require('./package').devDependencies).join('\n')`"" | `
sls "^eslint(-|$)" | `
%{ npm rm --silent --save-dev $_ }
# Setup Node.js version-specific dependencies
- ps: |
# mocha for testing
# - use 2.x for Node.js < 0.10
# - use 3.x for Node.js < 4
# - use 5.x for Node.js < 6
# - use 6.x for Node.js < 8
# - use 7.x for Node.js < 10
if ([int]$env:nodejs_version.split(".")[0] -eq 0 -and [int]$env:nodejs_version.split(".")[1] -lt 10) {
npm install --silent --save-dev mocha@2.5.3
} elseif ([int]$env:nodejs_version.split(".")[0] -lt 4) {
npm install --silent --save-dev mocha@3.5.3
} elseif ([int]$env:nodejs_version.split(".")[0] -lt 6) {
npm install --silent --save-dev mocha@5.2.0
} elseif ([int]$env:nodejs_version.split(".")[0] -lt 8) {
npm install --silent --save-dev mocha@6.2.2
} elseif ([int]$env:nodejs_version.split(".")[0] -lt 10) {
npm install --silent --save-dev mocha@7.2.0
}
- ps: |
# mocha for testing
# - use 1.1.0 for Node.js < 0.10
# - use 2.0.0 for Node.js < 4
# - use 3.4.2 for Node.js < 6
if ([int]$env:nodejs_version.split(".")[0] -eq 0 -and [int]$env:nodejs_version.split(".")[1] -lt 10) {
npm install --silent --save-dev supertest@1.1.0
} elseif ([int]$env:nodejs_version.split(".")[0] -lt 4) {
npm install --silent --save-dev supertest@2.0.0
} elseif ([int]$env:nodejs_version.split(".")[0] -lt 6) {
npm install --silent --save-dev supertest@3.4.2
}
# Update Node.js modules
- ps: |
# Prune & rebuild node_modules
if (Test-Path -Path node_modules) {
npm prune
npm rebuild
}
# Install Node.js modules
- npm install
build: off
test_script:
# Output version data
- ps: |
node --version
npm --version
# Run test script
- npm test
version: "{build}"

408
index.js
View File

@@ -1,23 +1,23 @@
/*!
* serve-index
* Copyright(c) 2011 Sencha Inc.
* Copyright(c) 2011 TJ Holowaychuk
* Copyright(c) 2014 Douglas Christopher Wilson
* Copyright(c) 2014-2015 Douglas Christopher Wilson
* MIT Licensed
*/
// TODO: arrow key navigation
// TODO: make icons extensible
'use strict';
/**
* Module dependencies.
* @private
*/
var accepts = require('accepts');
var createError = require('http-errors');
var debug = require('debug')('serve-index');
var http = require('http')
, fs = require('fs')
var escapeHtml = require('escape-html');
var fs = require('fs')
, path = require('path')
, normalize = path.normalize
, sep = path.sep
@@ -28,6 +28,13 @@ var mime = require('mime-types');
var parseUrl = require('parseurl');
var resolve = require('path').resolve;
/**
* Module exports.
* @public
*/
module.exports = serveIndex;
/*!
* Icon cache.
*/
@@ -67,56 +74,64 @@ var mediaType = {
*
* See Readme.md for documentation of options.
*
* @param {String} path
* @param {String} root
* @param {Object} options
* @return {Function} middleware
* @api public
* @public
*/
exports = module.exports = function serveIndex(root, options){
options = options || {};
function serveIndex(root, options) {
var opts = options || {};
// root required
if (!root) throw new TypeError('serveIndex() root path required');
if (!root) {
throw new TypeError('serveIndex() root path required');
}
// resolve root to absolute
root = resolve(root);
// resolve root to absolute and normalize
var rootPath = normalize(resolve(root) + sep);
var hidden = options.hidden
, icons = options.icons
, view = options.view || 'tiles'
, filter = options.filter
, template = options.template || defaultTemplate
, stylesheet = options.stylesheet || defaultStylesheet;
var filter = opts.filter;
var hidden = opts.hidden;
var icons = opts.icons;
var stylesheet = opts.stylesheet || defaultStylesheet;
var template = opts.template || defaultTemplate;
var view = opts.view || 'tiles';
return function serveIndex(req, res, next) {
return function (req, res, next) {
if (req.method !== 'GET' && req.method !== 'HEAD') {
res.statusCode = 'OPTIONS' === req.method
? 200
: 405;
res.statusCode = 'OPTIONS' === req.method ? 200 : 405;
res.setHeader('Allow', 'GET, HEAD, OPTIONS');
res.setHeader('Content-Length', '0');
res.end();
return;
}
// parse URLs
var url = parseUrl(req);
var originalUrl = parseUrl.original(req);
// get dir
var dir = getRequestedDir(req)
var dir = decodeURIComponent(url.pathname)
, path = normalize(join(root, dir))
, originalDir = decodeURIComponent(originalUrl.pathname)
var showUp = resolve(path) !== root;
// bad request
if (dir === null) return next(createError(400))
// parse URLs
var originalUrl = parseUrl.original(req);
var originalDir = decodeURIComponent(originalUrl.pathname);
// join / normalize from root dir
var path = normalize(join(rootPath, dir));
// null byte(s), bad request
if (~path.indexOf('\0')) return next(createError(400));
// malicious path
if (path.substr(0, root.length) !== root) {
if ((path + sep).substr(0, rootPath.length) !== rootPath) {
debug('malicious path "%s"', path);
return next(createError(403));
}
// determine ".." display
var showUp = normalize(resolve(path) + sep) !== rootPath;
// check if we have a directory
debug('stat "%s"', path);
fs.stat(path, function(err, stat){
@@ -138,16 +153,18 @@ exports = module.exports = function serveIndex(root, options){
fs.readdir(path, function(err, files){
if (err) return next(err);
if (!hidden) files = removeHidden(files);
if (filter) files = files.filter(filter);
if (filter) files = files.filter(function(filename, index, list) {
return filter(filename, index, list, path);
});
files.sort();
// content-negotiation
var accept = accepts(req);
var type = accept.types(mediaTypes);
var type = accept.type(mediaTypes);
// not acceptable
if (!type) return next(createError(406));
exports[mediaType[type]](req, res, files, next, originalDir, showUp, icons, path, view, template, stylesheet);
serveIndex[mediaType[type]](req, res, files, next, originalDir, showUp, icons, path, view, template, stylesheet);
});
});
};
@@ -157,26 +174,40 @@ exports = module.exports = function serveIndex(root, options){
* Respond with text/html.
*/
exports.html = function(req, res, files, next, dir, showUp, icons, path, view, template, stylesheet){
fs.readFile(template, 'utf8', function(err, str){
if (err) return next(err);
fs.readFile(stylesheet, 'utf8', function(err, style){
if (err) return next(err);
stat(path, files, function(err, stats){
if (err) return next(err);
files = files.map(function(file, i){ return { name: file, stat: stats[i] }; });
files.sort(fileSort);
if (showUp) files.unshift({ name: '..' });
str = str
.replace('{style}', style.concat(iconStyle(files, icons)))
.replace('{files}', html(files, dir, icons, view))
.replace('{directory}', dir)
.replace('{linked-path}', htmlPath(dir));
serveIndex.html = function _html(req, res, files, next, dir, showUp, icons, path, view, template, stylesheet) {
var render = typeof template !== 'function'
? createHtmlRender(template)
: template
var buf = new Buffer(str, 'utf8');
res.setHeader('Content-Type', 'text/html; charset=utf-8');
res.setHeader('Content-Length', buf.length);
res.end(buf);
if (showUp) {
files.unshift('..');
}
// stat all files
stat(path, files, function (err, fileList) {
if (err) return next(err);
// sort file list
fileList.sort(fileSort);
// read stylesheet
fs.readFile(stylesheet, 'utf8', function (err, style) {
if (err) return next(err);
// create locals for rendering
var locals = {
directory: dir,
displayIcons: Boolean(icons),
fileList: fileList,
path: path,
style: style,
viewName: view
};
// render html
render(locals, function (err, body) {
if (err) return next(err);
send(res, 'text/html', body)
});
});
});
@@ -186,63 +217,175 @@ exports.html = function(req, res, files, next, dir, showUp, icons, path, view, t
* Respond with application/json.
*/
exports.json = function(req, res, files){
var body = JSON.stringify(files);
var buf = new Buffer(body, 'utf8');
serveIndex.json = function _json (req, res, files, next, dir, showUp, icons, path) {
// stat all files
stat(path, files, function (err, fileList) {
if (err) return next(err)
res.setHeader('Content-Type', 'application/json; charset=utf-8');
res.setHeader('Content-Length', buf.length);
res.end(buf);
// sort file list
fileList.sort(fileSort)
// serialize
var body = JSON.stringify(fileList.map(function (file) {
return file.name
}))
send(res, 'application/json', body)
})
};
/**
* Respond with text/plain.
*/
exports.plain = function(req, res, files){
var body = files.join('\n') + '\n';
var buf = new Buffer(body, 'utf8');
serveIndex.plain = function _plain (req, res, files, next, dir, showUp, icons, path) {
// stat all files
stat(path, files, function (err, fileList) {
if (err) return next(err)
res.setHeader('Content-Type', 'text/plain; charset=utf-8');
res.setHeader('Content-Length', buf.length);
res.end(buf);
// sort file list
fileList.sort(fileSort)
// serialize
var body = fileList.map(function (file) {
return file.name
}).join('\n') + '\n'
send(res, 'text/plain', body)
})
};
/**
* Generate an `Error` from the given status `code`
* and optional `msg`.
*
* @param {Number} code
* @param {String} msg
* @return {Error}
* @api private
* Map html `files`, returning an html unordered list.
* @private
*/
function createError(code, msg) {
var err = new Error(msg || http.STATUS_CODES[code]);
err.status = code;
return err;
};
function createHtmlFileList(files, dir, useIcons, view) {
var html = '<ul id="files" class="view-' + escapeHtml(view) + '">'
+ (view === 'details' ? (
'<li class="header">'
+ '<span class="name">Name</span>'
+ '<span class="size">Size</span>'
+ '<span class="date">Modified</span>'
+ '</li>') : '');
html += files.map(function (file) {
var classes = [];
var isDir = file.stat && file.stat.isDirectory();
var path = dir.split('/').map(function (c) { return encodeURIComponent(c); });
if (useIcons) {
classes.push('icon');
if (isDir) {
classes.push('icon-directory');
} else {
var ext = extname(file.name);
var icon = iconLookup(file.name);
classes.push('icon');
classes.push('icon-' + ext.substring(1));
if (classes.indexOf(icon.className) === -1) {
classes.push(icon.className);
}
}
}
path.push(encodeURIComponent(file.name));
var date = file.stat && file.name !== '..'
? file.stat.mtime.toLocaleDateString() + ' ' + file.stat.mtime.toLocaleTimeString()
: '';
var size = file.stat && !isDir
? file.stat.size
: '';
return '<li><a href="'
+ escapeHtml(normalizeSlashes(normalize(path.join('/'))))
+ '" class="' + escapeHtml(classes.join(' ')) + '"'
+ ' title="' + escapeHtml(file.name) + '">'
+ '<span class="name">' + escapeHtml(file.name) + '</span>'
+ '<span class="size">' + escapeHtml(size) + '</span>'
+ '<span class="date">' + escapeHtml(date) + '</span>'
+ '</a></li>';
}).join('\n');
html += '</ul>';
return html;
}
/**
* Create function to render html.
*/
function createHtmlRender(template) {
return function render(locals, callback) {
// read template
fs.readFile(template, 'utf8', function (err, str) {
if (err) return callback(err);
var body = str
.replace(/\{style\}/g, locals.style.concat(iconStyle(locals.fileList, locals.displayIcons)))
.replace(/\{files\}/g, createHtmlFileList(locals.fileList, locals.directory, locals.displayIcons, locals.viewName))
.replace(/\{directory\}/g, escapeHtml(locals.directory))
.replace(/\{linked-path\}/g, htmlPath(locals.directory));
callback(null, body);
});
};
}
/**
* Sort function for with directories first.
*/
function fileSort(a, b) {
// sort ".." to the top
if (a.name === '..' || b.name === '..') {
return a.name === b.name ? 0
: a.name === '..' ? -1 : 1;
}
return Number(b.stat && b.stat.isDirectory()) - Number(a.stat && a.stat.isDirectory()) ||
String(a.name).toLocaleLowerCase().localeCompare(String(b.name).toLocaleLowerCase());
}
/**
* Get the requested directory from request.
*
* @param req
* @return {string}
* @api private
*/
function getRequestedDir (req) {
try {
return decodeURIComponent(parseUrl(req).pathname)
} catch (e) {
return null
}
}
/**
* Map html `dir`, returning a linked path.
*/
function htmlPath(dir) {
var curr = [];
return dir.split('/').map(function(part){
curr.push(encodeURIComponent(part));
return part ? '<a href="' + curr.join('/') + '">' + part + '</a>' : '';
}).join(' / ');
var parts = dir.split('/');
var crumb = new Array(parts.length);
for (var i = 0; i < parts.length; i++) {
var part = parts[i];
if (part) {
parts[i] = encodeURIComponent(part);
crumb[i] = '<a href="' + escapeHtml(parts.slice(0, i + 1).join('/')) + '">' + escapeHtml(part) + '</a>';
}
}
return crumb.join(' / ');
}
/**
@@ -273,7 +416,7 @@ function iconLookup(filename) {
// try by mime type
if (icons[mimetype]) {
return {
className: 'icon-' + mimetype.replace('/', '-'),
className: 'icon-' + mimetype.replace('/', '-').replace('+', '_'),
fileName: icons[mimetype]
};
}
@@ -307,11 +450,9 @@ function iconLookup(filename) {
* Load icon images, return css string.
*/
function iconStyle (files, useIcons) {
function iconStyle(files, useIcons) {
if (!useIcons) return '';
var className;
var i;
var iconName;
var list = [];
var rules = {};
var selector;
@@ -321,7 +462,7 @@ function iconStyle (files, useIcons) {
for (i = 0; i < files.length; i++) {
var file = files[i];
var isDir = '..' == file.name || (file.stat && file.stat.isDirectory());
var isDir = file.stat && file.stat.isDirectory();
var icon = isDir
? { className: 'icon-directory', fileName: icons.folder }
: iconLookup(file.name);
@@ -348,63 +489,6 @@ function iconStyle (files, useIcons) {
return style;
}
/**
* Map html `files`, returning an html unordered list.
*/
function html(files, dir, useIcons, view) {
return '<ul id="files" class="view-' + view + '">'
+ (view == 'details' ? (
'<li class="header">'
+ '<span class="name">Name</span>'
+ '<span class="size">Size</span>'
+ '<span class="date">Modified</span>'
+ '</li>') : '')
+ files.map(function(file){
var isDir = '..' == file.name || (file.stat && file.stat.isDirectory())
, classes = []
, path = dir.split('/').map(function (c) { return encodeURIComponent(c); });
if (useIcons) {
classes.push('icon');
if (isDir) {
classes.push('icon-directory');
} else {
var ext = extname(file.name);
var icon = iconLookup(file.name);
classes.push('icon');
classes.push('icon-' + ext.substring(1));
if (classes.indexOf(icon.className) === -1) {
classes.push(icon.className);
}
}
}
path.push(encodeURIComponent(file.name));
var date = file.stat && file.name !== '..'
? file.stat.mtime.toDateString() + ' ' + file.stat.mtime.toLocaleTimeString()
: '';
var size = file.stat && !isDir
? file.stat.size
: '';
return '<li><a href="'
+ normalizeSlashes(normalize(path.join('/')))
+ '" class="'
+ classes.join(' ') + '"'
+ ' title="' + file.name + '">'
+ '<span class="name">'+file.name+'</span>'
+ '<span class="size">'+size+'</span>'
+ '<span class="date">'+date+'</span>'
+ '</a></li>';
}).join('\n') + '</ul>';
}
/**
* Load and cache the given `icon`.
*
@@ -442,13 +526,34 @@ function normalizeSlashes(path) {
function removeHidden(files) {
return files.filter(function(file){
return '.' != file[0];
return file[0] !== '.'
});
}
/**
* Stat all files and return array of stat
* in same order.
* Send a response.
* @private
*/
function send (res, type, body) {
// security header for content sniffing
res.setHeader('X-Content-Type-Options', 'nosniff')
// standard headers
res.setHeader('Content-Type', type + '; charset=utf-8')
res.setHeader('Content-Length', Buffer.byteLength(body, 'utf8'))
// body
res.end(body, 'utf8')
}
/**
* Stat all files and return array of objects in the form
* `{ name, stat }`.
*
* @param {Array} files
* @return {Array}
* @api private
*/
function stat(dir, files, cb) {
@@ -462,7 +567,10 @@ function stat(dir, files, cb) {
if (err && err.code !== 'ENOENT') return done(err);
// pass ENOENT as null stat, not error
done(null, stat || null);
done(null, {
name: file,
stat: stat || null
})
});
});
});
@@ -480,6 +588,7 @@ var icons = {
'folder': 'folder.png',
// generic mime type icons
'font': 'font.png',
'image': 'image.png',
'text': 'page_white_text.png',
'video': 'film.png',
@@ -490,7 +599,6 @@ var icons = {
'+zip': 'box.png',
// specific mime type icons
'application/font-woff': 'font.png',
'application/javascript': 'page_white_code_red.png',
'application/json': 'page_white_code.png',
'application/msword': 'page_white_word.png',
@@ -504,7 +612,6 @@ var icons = {
'application/vnd.oasis.opendocument.text': 'page_white_word.png',
'application/x-7z-compressed': 'box.png',
'application/x-sh': 'application_xp_terminal.png',
'application/x-font-ttf': 'font.png',
'application/x-msaccess': 'page_white_database.png',
'application/x-shockwave-flash': 'page_white_flash.png',
'application/x-sql': 'page_white_database.png',
@@ -558,7 +665,6 @@ var icons = {
'.map': 'map.png',
'.msi': 'box.png',
'.mv4': 'film.png',
'.otf': 'font.png',
'.pdb': 'page_white_database.png',
'.php': 'page_white_php.png',
'.pl': 'page_white_code.png',

View File

@@ -1,22 +1,30 @@
{
"name": "serve-index",
"description": "Serve directory listings",
"version": "1.3.0",
"version": "1.9.1",
"author": "Douglas Christopher Wilson <doug@somethingdoug.com>",
"license": "MIT",
"repository": "expressjs/serve-index",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/express"
},
"dependencies": {
"accepts": "~1.1.0",
"batch": "0.5.1",
"debug": "~2.0.0",
"mime-types": "~2.0.1",
"parseurl": "~1.3.0"
"accepts": "~1.3.7",
"batch": "0.6.1",
"debug": "2.6.9",
"escape-html": "~1.0.3",
"http-errors": "~1.8.0",
"mime-types": "~2.1.29",
"parseurl": "~1.3.3"
},
"devDependencies": {
"istanbul": "0.3.2",
"mocha": "~1.21.1",
"should": "~4.0.0",
"supertest": "~0.13.0"
"after": "0.8.2",
"eslint": "7.23.0",
"eslint-plugin-markdown": "2.0.0",
"mocha": "10.4.0",
"nyc": "15.1.0",
"supertest": "7.0.0"
},
"files": [
"public/",
@@ -28,8 +36,9 @@
"node": ">= 0.8.0"
},
"scripts": {
"lint": "eslint .",
"test": "mocha --reporter spec --bail --check-leaks test/",
"test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot --check-leaks test/",
"test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter spec --check-leaks test/"
"test-ci": "nyc --reporter=lcov --reporter=text npm test",
"test-cov": "nyc --reporter=html --reporter=text npm test"
}
}

View File

@@ -52,11 +52,11 @@
}
function search() {
var str = $('search').value
, links = $('files').all('a');
var str = $('search').value.toLowerCase();
var links = $('files').all('a');
links.each(function(link){
var text = link.textContent;
var text = link.textContent.toLowerCase();
if ('..' == text) return;
if (str.length && ~text.indexOf(str)) {
@@ -75,7 +75,7 @@
<body class="directory">
<input id="search" type="text" placeholder="Search" autocomplete="off" />
<div id="wrapper">
<h1>{linked-path}</h1>
<h1><a href="/">~</a>{linked-path}</h1>
{files}
</div>
</body>

View File

@@ -249,7 +249,7 @@ ul#files.view-details li.header {
display: inline-block;
width: 100%;
text-indent: 0;
background-position: 0 0;
background-position: 0 50%;
}
#files .icon .name {
text-indent: 41px;

View File

1
test/fixtures/users/#dir/tobi.txt vendored Normal file
View File

@@ -0,0 +1 @@
ferret

View File

@@ -1,26 +0,0 @@
var bytes = require('bytes');
exports['default request body'] = function(app){
it('should default to {}', function(done){
app.request()
.post('/')
.end(function(res){
res.body.should.equal('{}');
done();
})
})
};
exports['limit body to'] = function(size, type, app){
it('should accept a limit option', function(done){
app.request()
.post('/')
.set('Content-Length', bytes(size) + 1)
.set('Content-Type', type)
.end(function(res){
res.should.have.status(413);
done();
})
})
}

View File

@@ -6,6 +6,7 @@
</head>
<body class="directory">
<h1>This is the test template</h1>
<h2>directory {directory}</h2>
<div id="wrapper">
<h1>{linked-path}</h1>
{files}

File diff suppressed because it is too large Load Diff