UNPKG

5.38 kBJavaScriptView Raw
1import { RequestCookieStore } from "@worker-tools/request-cookie-store";
2import { SignedCookieStore } from "@worker-tools/signed-cookie-store";
3import { EncryptedCookieStore } from "@worker-tools/encrypted-cookie-store";
4import { ResolvablePromise } from '@worker-tools/resolvable-promise';
5import { forbidden } from "@worker-tools/response-creators";
6import { MiddlewareCookieStore } from "./utils/middleware-cookie-store.js";
7import { headersSetCookieFix } from './utils/headers-set-cookie-fix.js';
8import { unsettle } from "./utils/unsettle.js";
9export async function cookiesFrom(cookieStore) {
10 return Object.fromEntries((await cookieStore.getAll()).map(({ name, value }) => [name, value]));
11}
12export 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};
41export { plainCookies as unsignedCookies };
42export const signedCookies = (opts) => {
43 // TODO: options to provide own cryptokey??
44 // TODO: What if secret isn't known at initialization (e.g. Cloudflare Workers)
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 // Wait for all set cookie promises to settle
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};
89export const encryptedCookies = (opts) => {
90 // TODO: options to provide own cryptokey??
91 // TODO: What if secret isn't known at initialization (e.g. Cloudflare Workers)
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 // Wait for all set cookie promises to settle
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//# sourceMappingURL=cookies.js.map
\No newline at end of file