@ya-accelerators/nextjs-framework 0.0.92 → 0.0.94
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/lib/index.d.ts +2 -0
- package/dist/lib/index.js +2 -0
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/uploads/index.d.ts +4 -0
- package/dist/lib/uploads/index.js +64 -0
- package/dist/lib/uploads/index.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/ui/composite/index.d.ts +2 -5
- package/dist/ui/composite/input/file/index.d.ts +2 -5
- package/dist/ui/composite/input/file/index.jsx +11 -39
- package/dist/ui/composite/input/file/index.jsx.map +1 -1
- package/dist/ui/composite/input/index.d.ts +2 -5
- package/dist/ui/layout/form/index.d.ts +2 -5
- package/dist/ui/layout/form/index.jsx +2 -2
- package/dist/ui/layout/form/index.jsx.map +1 -1
- package/dist/ui/layout/form/renderItem.d.ts +2 -5
- package/dist/ui/layout/form/renderItem.jsx +2 -2
- package/dist/ui/layout/form/renderItem.jsx.map +1 -1
- package/dist/ui/layout/index.d.ts +16 -13
- package/dist/ui/layout/tab/component.d.ts +6 -3
- package/dist/ui/layout/tab/component.jsx +8 -8
- package/dist/ui/layout/tab/component.jsx.map +1 -1
- package/dist/ui/layout/tab/index.d.ts +14 -6
- package/dist/ui/layout/tab/index.jsx +34 -10
- package/dist/ui/layout/tab/index.jsx.map +1 -1
- package/package.json +1 -1
package/dist/lib/index.d.ts
CHANGED
|
@@ -2,9 +2,11 @@ import * as cookie from './cookie';
|
|
|
2
2
|
import * as nextAuth from './next-auth';
|
|
3
3
|
import * as serverAction from './server-action';
|
|
4
4
|
import * as trpc from './trpc';
|
|
5
|
+
import * as uploads from './uploads';
|
|
5
6
|
export declare const Lib: {
|
|
6
7
|
cookie: typeof cookie;
|
|
7
8
|
nextAuth: typeof nextAuth;
|
|
8
9
|
serverAction: typeof serverAction;
|
|
9
10
|
trpc: typeof trpc;
|
|
11
|
+
uploads: typeof uploads;
|
|
10
12
|
};
|
package/dist/lib/index.js
CHANGED
|
@@ -2,10 +2,12 @@ import * as cookie from './cookie';
|
|
|
2
2
|
import * as nextAuth from './next-auth';
|
|
3
3
|
import * as serverAction from './server-action';
|
|
4
4
|
import * as trpc from './trpc';
|
|
5
|
+
import * as uploads from './uploads';
|
|
5
6
|
export const Lib = {
|
|
6
7
|
cookie,
|
|
7
8
|
nextAuth,
|
|
8
9
|
serverAction,
|
|
9
10
|
trpc,
|
|
11
|
+
uploads,
|
|
10
12
|
};
|
|
11
13
|
//# sourceMappingURL=index.js.map
|
package/dist/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,UAAU,CAAA;AAClC,OAAO,KAAK,QAAQ,MAAM,aAAa,CAAA;AACvC,OAAO,KAAK,YAAY,MAAM,iBAAiB,CAAA;AAC/C,OAAO,KAAK,IAAI,MAAM,QAAQ,CAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,UAAU,CAAA;AAClC,OAAO,KAAK,QAAQ,MAAM,aAAa,CAAA;AACvC,OAAO,KAAK,YAAY,MAAM,iBAAiB,CAAA;AAC/C,OAAO,KAAK,IAAI,MAAM,QAAQ,CAAA;AAC9B,OAAO,KAAK,OAAO,MAAM,WAAW,CAAA;AAEpC,MAAM,CAAC,MAAM,GAAG,GAAG;IACjB,MAAM;IACN,QAAQ;IACR,YAAY;IACZ,IAAI;IACJ,OAAO;CACR,CAAA"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { logger } from '../../logger';
|
|
2
|
+
// Same-origin upload relay. The browser POSTs the file bytes to the app's own origin and this route
|
|
3
|
+
// forwards them to the backend's `/_uploads` sink: the one-time token and the target URL are resolved
|
|
4
|
+
// server-side by `uploadAction`, so the token never reaches the browser and the page never makes a
|
|
5
|
+
// cross-origin request (no CORS preflight, and no mixed content when the page is served over https while
|
|
6
|
+
// the backend is plain http in dev). The destination is not caller-supplied, so this is not an open relay.
|
|
7
|
+
export const createUploadRoute = (uploadAction) => async (request) => {
|
|
8
|
+
// Unlike a Server Action, a route handler gets no framework CSRF protection, and this one is
|
|
9
|
+
// cookie-authenticated: without this check an attacker's page could POST a body cross-site and have the
|
|
10
|
+
// victim's session mint a token and store the object. Two accept conditions, because neither covers both
|
|
11
|
+
// deployments on its own: `Sec-Fetch-Site` is browser-set and a forbidden header name (unforgeable) but
|
|
12
|
+
// is only attached to trustworthy origins, so it is absent on the plain-http dev hosts; the Origin/Host
|
|
13
|
+
// comparison covers those, and compares against `Host` alone — `x-forwarded-host` is caller-settable, so
|
|
14
|
+
// trusting it would let an attacker match its own Origin.
|
|
15
|
+
const origin = request.headers.get('origin');
|
|
16
|
+
if (request.headers.get('sec-fetch-site') !== 'same-origin' &&
|
|
17
|
+
(origin === null || URL.parse(origin)?.host !== request.headers.get('host'))) {
|
|
18
|
+
return new Response(JSON.stringify({ error: 'cross-origin upload rejected' }), {
|
|
19
|
+
status: 403,
|
|
20
|
+
headers: { 'content-type': 'application/json' },
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
const filename = request.headers.get('x-upload-filename');
|
|
24
|
+
const minted = await uploadAction().catch((error) => {
|
|
25
|
+
logger.error('upload', { error });
|
|
26
|
+
return undefined;
|
|
27
|
+
});
|
|
28
|
+
if (minted === undefined) {
|
|
29
|
+
return new Response(JSON.stringify({ error: 'upload token could not be issued' }), {
|
|
30
|
+
status: 502,
|
|
31
|
+
headers: { 'content-type': 'application/json' },
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
const { token, url } = minted;
|
|
35
|
+
const response = await fetch(url, {
|
|
36
|
+
method: 'POST',
|
|
37
|
+
headers: {
|
|
38
|
+
authorization: `Bearer ${token}`,
|
|
39
|
+
// Forwarded only when present — the backend falls back to its own default name for an absent header,
|
|
40
|
+
// but an empty string would be taken as the real filename.
|
|
41
|
+
...(filename === null ? {} : { 'x-upload-filename': filename }),
|
|
42
|
+
'content-type': request.headers.get('content-type') ?? 'application/octet-stream',
|
|
43
|
+
},
|
|
44
|
+
// The body is buffered rather than streamed: passing `request.body` through requires the
|
|
45
|
+
// `duplex: 'half'` init option, which the DOM `RequestInit` type Next.js compiles against does not
|
|
46
|
+
// declare. The backend caps a single upload at its own ceiling, so the buffer stays bounded.
|
|
47
|
+
body: await request.arrayBuffer(),
|
|
48
|
+
}).catch((error) => {
|
|
49
|
+
logger.error('upload', { url, error });
|
|
50
|
+
return undefined;
|
|
51
|
+
});
|
|
52
|
+
if (response === undefined) {
|
|
53
|
+
return new Response(JSON.stringify({ error: 'upload backend unreachable' }), {
|
|
54
|
+
status: 502,
|
|
55
|
+
headers: { 'content-type': 'application/json' },
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
const body = await response.text();
|
|
59
|
+
if (!response.ok) {
|
|
60
|
+
logger.error('upload', { status: response.status, body });
|
|
61
|
+
}
|
|
62
|
+
return new Response(body, { status: response.status, headers: { 'content-type': 'application/json' } });
|
|
63
|
+
};
|
|
64
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/lib/uploads/index.ts"],"names":[],"mappings":"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"}
|