appstage 0.2.17 → 0.2.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +28 -18
- package/dist/index.d.ts +2 -1
- package/dist/index.mjs +28 -18
- package/package.json +1 -1
- package/src/controllers/files.ts +41 -32
package/dist/index.cjs
CHANGED
|
@@ -81,32 +81,39 @@ const defaultExtensions = ["html", "htm"];
|
|
|
81
81
|
const defaultPath = (req) => req.path;
|
|
82
82
|
const defaultLanguages = getLanguageList;
|
|
83
83
|
/**
|
|
84
|
-
* Serves files from the specified directory path in a locale-aware
|
|
84
|
+
* Serves files from the specified directory path or paths in a locale-aware
|
|
85
85
|
* fashion after applying optional transforms.
|
|
86
86
|
*/
|
|
87
87
|
const files = (params) => {
|
|
88
88
|
let p = typeof params === "string" ? { base: params } : params;
|
|
89
89
|
let bases = Array.isArray(p.base) ? p.base : [p.base];
|
|
90
90
|
let exts = p.extensions ?? defaultExtensions;
|
|
91
|
-
|
|
92
|
-
|
|
91
|
+
let fallthrough = p.fallthrough ?? true;
|
|
92
|
+
return async (req, res, next) => {
|
|
93
93
|
let path = typeof p.path === "string" ? p.path : (p.path ?? defaultPath)(req);
|
|
94
94
|
if (!matches(path, p.matches)) {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
95
|
+
if (fallthrough) next();
|
|
96
|
+
else {
|
|
97
|
+
emitLog(req.app, "Unmatched path", { data: { path } });
|
|
98
|
+
res.status(404).send(await req.app.renderStatus?.(req, res, {
|
|
99
|
+
code: "unmatched_path",
|
|
100
|
+
path
|
|
101
|
+
}));
|
|
102
|
+
}
|
|
100
103
|
return;
|
|
101
104
|
}
|
|
102
105
|
if (path.includes("../")) {
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
106
|
+
if (fallthrough) next();
|
|
107
|
+
else {
|
|
108
|
+
emitLog(req.app, "Invalid path (potential traversal attempt)", { data: { path } });
|
|
109
|
+
res.status(400).send(await req.app.renderStatus?.(req, res, {
|
|
110
|
+
code: "invalid_path",
|
|
111
|
+
path
|
|
112
|
+
}));
|
|
113
|
+
}
|
|
108
114
|
return;
|
|
109
115
|
}
|
|
116
|
+
let langs = (p.languages ?? defaultLanguages)(req);
|
|
110
117
|
let filePath = null;
|
|
111
118
|
for (let k = 0; k < bases.length && filePath === null; k++) {
|
|
112
119
|
let base = bases[k];
|
|
@@ -121,11 +128,14 @@ const files = (params) => {
|
|
|
121
128
|
for (let i = 0; i < exts.length && filePath === null; i++) filePath = await resolve(base, path, `index.${exts[i]}`);
|
|
122
129
|
}
|
|
123
130
|
if (filePath === null) {
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
131
|
+
if (fallthrough) next();
|
|
132
|
+
else {
|
|
133
|
+
emitLog(req.app, "Unknown path", { data: { path } });
|
|
134
|
+
res.status(404).send(await req.app.renderStatus?.(req, res, {
|
|
135
|
+
code: "unknown_path",
|
|
136
|
+
path
|
|
137
|
+
}));
|
|
138
|
+
}
|
|
129
139
|
return;
|
|
130
140
|
}
|
|
131
141
|
if (!p.transform?.length) {
|
package/dist/index.d.ts
CHANGED
|
@@ -24,9 +24,10 @@ type FilesParams = {
|
|
|
24
24
|
extensions?: string[];
|
|
25
25
|
languages?: (req: Request) => string[];
|
|
26
26
|
transform?: TransformContent[];
|
|
27
|
+
fallthrough?: boolean;
|
|
27
28
|
};
|
|
28
29
|
/**
|
|
29
|
-
* Serves files from the specified directory path in a locale-aware
|
|
30
|
+
* Serves files from the specified directory path or paths in a locale-aware
|
|
30
31
|
* fashion after applying optional transforms.
|
|
31
32
|
*/
|
|
32
33
|
declare const files: Controller<string | FilesParams>;
|
package/dist/index.mjs
CHANGED
|
@@ -55,32 +55,39 @@ const defaultExtensions = ["html", "htm"];
|
|
|
55
55
|
const defaultPath = (req) => req.path;
|
|
56
56
|
const defaultLanguages = getLanguageList;
|
|
57
57
|
/**
|
|
58
|
-
* Serves files from the specified directory path in a locale-aware
|
|
58
|
+
* Serves files from the specified directory path or paths in a locale-aware
|
|
59
59
|
* fashion after applying optional transforms.
|
|
60
60
|
*/
|
|
61
61
|
const files = (params) => {
|
|
62
62
|
let p = typeof params === "string" ? { base: params } : params;
|
|
63
63
|
let bases = Array.isArray(p.base) ? p.base : [p.base];
|
|
64
64
|
let exts = p.extensions ?? defaultExtensions;
|
|
65
|
-
|
|
66
|
-
|
|
65
|
+
let fallthrough = p.fallthrough ?? true;
|
|
66
|
+
return async (req, res, next) => {
|
|
67
67
|
let path = typeof p.path === "string" ? p.path : (p.path ?? defaultPath)(req);
|
|
68
68
|
if (!matches(path, p.matches)) {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
69
|
+
if (fallthrough) next();
|
|
70
|
+
else {
|
|
71
|
+
emitLog(req.app, "Unmatched path", { data: { path } });
|
|
72
|
+
res.status(404).send(await req.app.renderStatus?.(req, res, {
|
|
73
|
+
code: "unmatched_path",
|
|
74
|
+
path
|
|
75
|
+
}));
|
|
76
|
+
}
|
|
74
77
|
return;
|
|
75
78
|
}
|
|
76
79
|
if (path.includes("../")) {
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
80
|
+
if (fallthrough) next();
|
|
81
|
+
else {
|
|
82
|
+
emitLog(req.app, "Invalid path (potential traversal attempt)", { data: { path } });
|
|
83
|
+
res.status(400).send(await req.app.renderStatus?.(req, res, {
|
|
84
|
+
code: "invalid_path",
|
|
85
|
+
path
|
|
86
|
+
}));
|
|
87
|
+
}
|
|
82
88
|
return;
|
|
83
89
|
}
|
|
90
|
+
let langs = (p.languages ?? defaultLanguages)(req);
|
|
84
91
|
let filePath = null;
|
|
85
92
|
for (let k = 0; k < bases.length && filePath === null; k++) {
|
|
86
93
|
let base = bases[k];
|
|
@@ -95,11 +102,14 @@ const files = (params) => {
|
|
|
95
102
|
for (let i = 0; i < exts.length && filePath === null; i++) filePath = await resolve$1(base, path, `index.${exts[i]}`);
|
|
96
103
|
}
|
|
97
104
|
if (filePath === null) {
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
105
|
+
if (fallthrough) next();
|
|
106
|
+
else {
|
|
107
|
+
emitLog(req.app, "Unknown path", { data: { path } });
|
|
108
|
+
res.status(404).send(await req.app.renderStatus?.(req, res, {
|
|
109
|
+
code: "unknown_path",
|
|
110
|
+
path
|
|
111
|
+
}));
|
|
112
|
+
}
|
|
103
113
|
return;
|
|
104
114
|
}
|
|
105
115
|
if (!p.transform?.length) {
|
package/package.json
CHANGED
package/src/controllers/files.ts
CHANGED
|
@@ -69,6 +69,7 @@ export type FilesParams = {
|
|
|
69
69
|
extensions?: string[];
|
|
70
70
|
languages?: (req: Request) => string[];
|
|
71
71
|
transform?: TransformContent[];
|
|
72
|
+
fallthrough?: boolean;
|
|
72
73
|
};
|
|
73
74
|
|
|
74
75
|
const defaultExtensions = ["html", "htm"];
|
|
@@ -76,7 +77,7 @@ const defaultPath = (req: Request) => req.path;
|
|
|
76
77
|
const defaultLanguages = getLanguageList;
|
|
77
78
|
|
|
78
79
|
/**
|
|
79
|
-
* Serves files from the specified directory path in a locale-aware
|
|
80
|
+
* Serves files from the specified directory path or paths in a locale-aware
|
|
80
81
|
* fashion after applying optional transforms.
|
|
81
82
|
*/
|
|
82
83
|
export const files: Controller<string | FilesParams> = (params) => {
|
|
@@ -84,45 +85,50 @@ export const files: Controller<string | FilesParams> = (params) => {
|
|
|
84
85
|
|
|
85
86
|
let bases = Array.isArray(p.base) ? p.base : [p.base];
|
|
86
87
|
let exts = p.extensions ?? defaultExtensions;
|
|
88
|
+
let fallthrough = p.fallthrough ?? true;
|
|
87
89
|
|
|
88
|
-
return async (req, res) => {
|
|
89
|
-
let langs = (p.languages ?? defaultLanguages)(req);
|
|
90
|
-
|
|
90
|
+
return async (req, res, next) => {
|
|
91
91
|
let path =
|
|
92
92
|
typeof p.path === "string" ? p.path : (p.path ?? defaultPath)(req);
|
|
93
93
|
|
|
94
94
|
if (!matches(path, p.matches)) {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
95
|
+
if (fallthrough) next();
|
|
96
|
+
else {
|
|
97
|
+
emitLog(req.app, "Unmatched path", { data: { path } });
|
|
98
|
+
|
|
99
|
+
res.status(404).send(
|
|
100
|
+
await req.app.renderStatus?.(req, res, {
|
|
101
|
+
code: "unmatched_path",
|
|
102
|
+
path,
|
|
103
|
+
}),
|
|
104
|
+
);
|
|
105
|
+
}
|
|
103
106
|
|
|
104
107
|
return;
|
|
105
108
|
}
|
|
106
109
|
|
|
107
110
|
if (path.includes("../")) {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
111
|
+
if (fallthrough) next();
|
|
112
|
+
else {
|
|
113
|
+
emitLog(req.app, "Invalid path (potential traversal attempt)", {
|
|
114
|
+
data: { path },
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
res.status(400).send(
|
|
118
|
+
await req.app.renderStatus?.(req, res, {
|
|
119
|
+
code: "invalid_path",
|
|
120
|
+
path,
|
|
121
|
+
}),
|
|
122
|
+
);
|
|
123
|
+
}
|
|
118
124
|
|
|
119
125
|
return;
|
|
120
126
|
}
|
|
121
127
|
|
|
128
|
+
let langs = (p.languages ?? defaultLanguages)(req);
|
|
122
129
|
let filePath: string | null = null;
|
|
123
130
|
|
|
124
|
-
//
|
|
125
|
-
// langs: en, ru
|
|
131
|
+
// Example: path = /x, langs = [en, ru], exts = [html, htm]
|
|
126
132
|
for (let k = 0; k < bases.length && filePath === null; k++) {
|
|
127
133
|
let base = bases[k];
|
|
128
134
|
|
|
@@ -167,14 +173,17 @@ export const files: Controller<string | FilesParams> = (params) => {
|
|
|
167
173
|
}
|
|
168
174
|
|
|
169
175
|
if (filePath === null) {
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
176
|
+
if (fallthrough) next();
|
|
177
|
+
else {
|
|
178
|
+
emitLog(req.app, "Unknown path", { data: { path } });
|
|
179
|
+
|
|
180
|
+
res.status(404).send(
|
|
181
|
+
await req.app.renderStatus?.(req, res, {
|
|
182
|
+
code: "unknown_path",
|
|
183
|
+
path,
|
|
184
|
+
}),
|
|
185
|
+
);
|
|
186
|
+
}
|
|
178
187
|
|
|
179
188
|
return;
|
|
180
189
|
}
|