1 | import { RequestCookieStore } from "@worker-tools/request-cookie-store";
|
2 | import { SignedCookieStore } from "@worker-tools/signed-cookie-store";
|
3 | import { EncryptedCookieStore } from "@worker-tools/encrypted-cookie-store";
|
4 | import { ResolvablePromise } from '@worker-tools/resolvable-promise';
|
5 | import { forbidden } from "@worker-tools/response-creators";
|
6 | import { MiddlewareCookieStore } from "./utils/middleware-cookie-store.js";
|
7 | import { headersSetCookieFix } from './utils/headers-set-cookie-fix.js';
|
8 | import { unsettle } from "./utils/unsettle.js";
|
9 | export async function cookiesFrom(cookieStore) {
|
10 | return Object.fromEntries((await cookieStore.getAll()).map(({ name, value }) => [name, value]));
|
11 | }
|
12 | export const plainCookies = () => async (ax) => {
|
13 | const x = await ax;
|
14 | const cookieStore = new RequestCookieStore(x.request);
|
15 | const requestDuration = new ResolvablePromise();
|
16 | const unsignedCookieStore = new MiddlewareCookieStore(cookieStore, requestDuration);
|
17 | const unsignedCookies = await cookiesFrom(unsignedCookieStore);
|
18 | const nx = Object.assign(x, {
|
19 | cookieStore: unsignedCookieStore,
|
20 | cookies: unsignedCookies,
|
21 | unsignedCookieStore,
|
22 | unsignedCookies,
|
23 | });
|
24 | x.effects.push(response => {
|
25 | requestDuration.resolve();
|
26 | const { headers: cookieHeaders } = cookieStore;
|
27 | if (cookieHeaders.length)
|
28 | response.headers.append('VARY', 'Cookie');
|
29 | const { status, statusText, headers, body } = response;
|
30 | return new Response(body, {
|
31 | status,
|
32 | statusText,
|
33 | headers: [
|
34 | ...headersSetCookieFix(headers),
|
35 | ...cookieHeaders,
|
36 | ],
|
37 | });
|
38 | });
|
39 | return nx;
|
40 | };
|
41 | export { plainCookies as unsignedCookies };
|
42 | export const signedCookies = (opts) => {
|
43 |
|
44 |
|
45 | if (!opts.secret)
|
46 | throw TypeError('Secret missing');
|
47 | const keyPromise = SignedCookieStore.deriveCryptoKey(opts);
|
48 | return async (ax) => {
|
49 | const x = await ax;
|
50 | const request = x.request;
|
51 | const cookieStore = new RequestCookieStore(request);
|
52 | const requestDuration = new ResolvablePromise();
|
53 | const signedCookieStore = new MiddlewareCookieStore(new SignedCookieStore(cookieStore, await keyPromise, {
|
54 | keyring: opts.keyring
|
55 | }), requestDuration);
|
56 | let signedCookies;
|
57 | try {
|
58 | signedCookies = await cookiesFrom(signedCookieStore);
|
59 | }
|
60 | catch {
|
61 | throw forbidden();
|
62 | }
|
63 | const nx = Object.assign(x, {
|
64 | cookieStore: signedCookieStore,
|
65 | cookies: signedCookies,
|
66 | signedCookieStore,
|
67 | signedCookies,
|
68 | });
|
69 | x.effects.push(async (response) => {
|
70 |
|
71 | requestDuration.resolve();
|
72 | await unsettle(signedCookieStore.allSettledPromise);
|
73 | const { headers: cookieHeaders } = cookieStore;
|
74 | if (cookieHeaders.length)
|
75 | response.headers.append('VARY', 'Cookie');
|
76 | const { status, statusText, headers, body } = response;
|
77 | return new Response(body, {
|
78 | status,
|
79 | statusText,
|
80 | headers: [
|
81 | ...headersSetCookieFix(headers),
|
82 | ...cookieHeaders,
|
83 | ],
|
84 | });
|
85 | });
|
86 | return nx;
|
87 | };
|
88 | };
|
89 | export const encryptedCookies = (opts) => {
|
90 |
|
91 |
|
92 | if (!opts.secret)
|
93 | throw TypeError('Secret missing');
|
94 | const keyPromise = EncryptedCookieStore.deriveCryptoKey(opts);
|
95 | return async (ax) => {
|
96 | const x = await ax;
|
97 | const request = x.request;
|
98 | const cookieStore = new RequestCookieStore(request);
|
99 | const requestDuration = new ResolvablePromise();
|
100 | const encryptedCookieStore = new MiddlewareCookieStore(new EncryptedCookieStore(cookieStore, await keyPromise, {
|
101 | keyring: opts.keyring
|
102 | }), requestDuration);
|
103 | let encryptedCookies;
|
104 | try {
|
105 | encryptedCookies = await cookiesFrom(encryptedCookieStore);
|
106 | }
|
107 | catch {
|
108 | throw forbidden();
|
109 | }
|
110 | const nx = Object.assign(x, {
|
111 | cookieStore: encryptedCookieStore,
|
112 | cookies: encryptedCookies,
|
113 | encryptedCookieStore,
|
114 | encryptedCookies,
|
115 | });
|
116 | x.effects.push(async (response) => {
|
117 |
|
118 | requestDuration.resolve();
|
119 | await unsettle(encryptedCookieStore.allSettledPromise);
|
120 | const { headers: cookieHeaders } = cookieStore;
|
121 | if (cookieHeaders.length)
|
122 | response.headers.append('VARY', 'Cookie');
|
123 | const { status, statusText, headers, body } = response;
|
124 | return new Response(body, {
|
125 | status,
|
126 | statusText,
|
127 | headers: [
|
128 | ...headersSetCookieFix(headers),
|
129 | ...cookieHeaders,
|
130 | ],
|
131 | });
|
132 | });
|
133 | return nx;
|
134 | };
|
135 | };
|
136 |
|
\ | No newline at end of file |