diff --git a/.changeset/late-mangos-tickle.md b/.changeset/late-mangos-tickle.md new file mode 100644 index 0000000..ca769b3 --- /dev/null +++ b/.changeset/late-mangos-tickle.md @@ -0,0 +1,6 @@ +--- +"webcrypt-session-example": patch +"webcrypt-session": patch +--- + +Add a live demo diff --git a/examples/cloudflare/src/index.ts b/examples/cloudflare/src/index.ts index 4ffb82f..77908d5 100644 --- a/examples/cloudflare/src/index.ts +++ b/examples/cloudflare/src/index.ts @@ -26,6 +26,35 @@ const sessionScheme = z.object({ const signInParamScheme = z.object({ username: z.string(), }); + +const welComePage = ` + +

Hello WebCrypt-Session

+

Please sign in first with sign-in.

+ +`; + +const welComeUserPage = ` + +

Hello WebCrypt-Session

+

Welcome, <%= username %>!

+

You can sign out with clicking following button.

+
+ +
+ +`; + +const signInPage = ` + +

Sign-In to WebCrypt-Session

+
+ + +
+ +`; + export default { async fetch( request: Request, @@ -40,12 +69,21 @@ export default { } ); const url = new URL(request.url); + const baseUrl = `${url.protocol}//${url.host}`; if (url.pathname === "/signIn") { - if (request.method !== "POST") { + if (request.method === "GET") { + return new Response(signInPage, { + headers: { + "content-type": "text/html;charset=UTF-8", + }, + }); + } else if (request.method !== "POST") { return new Response(null, { status: 405 }); } try { - const signInParam = signInParamScheme.parse(await request.json()); + const formData = await request.formData(); + const formObject = Object.fromEntries(formData.entries()); + const signInParam = signInParamScheme.parse(formObject); await webCryptSession.save({ username: signInParam.username, }); @@ -53,27 +91,43 @@ export default { if (session == null) { throw new Error(); } - return new Response(`Hello ${signInParam.username}`, { + return new Response(null, { + status: 303, headers: { + location: baseUrl, "Set-Cookie": session, }, }); - } catch { + } catch (_) { return new Response(null, { status: 400, }); } + } else if (url.pathname === "/signOut") { + return new Response(null, { + status: 303, + headers: { + location: baseUrl, + "Set-Cookie": "session=delete; expires=Thu, 01 Jan 1970 00:00:00 GMT", + }, + }); } const session = webCryptSession.username; if (session == null) { - return new Response( - "Please sign in first with http://localhost:8787/signIn" - ); + return new Response(welComePage, { + headers: { + "content-type": "text/html;charset=UTF-8", + }, + }); } - return new Response(`Hello ${webCryptSession.username}`, { - headers: { - "Set-Cookie": session, - }, - }); + return new Response( + welComeUserPage.replace("<%= username %>", webCryptSession.username), + { + headers: { + "Set-Cookie": webCryptSession.toHeaderValue() ?? "", + "content-type": "text/html;charset=UTF-8", + }, + } + ); }, }; diff --git a/examples/cloudflare/wrangler.toml b/examples/cloudflare/wrangler.toml index eb287ff..d3b6577 100644 --- a/examples/cloudflare/wrangler.toml +++ b/examples/cloudflare/wrangler.toml @@ -1,4 +1,4 @@ -name = "cloudflare" +name = "webcrypt-session" main = "src/index.ts" compatibility_date = "2022-06-14" tsconfig = "./tsconfig.json" diff --git a/packages/webcrypt-session/README.md b/packages/webcrypt-session/README.md index 4e46690..85598ba 100644 --- a/packages/webcrypt-session/README.md +++ b/packages/webcrypt-session/README.md @@ -1,5 +1,7 @@ # WebCrypt Session +demo: https://webcrypt-session.sat0shi.workers.dev/ + _🛠 Stateless session utility using signed and encrypted cookies to store data. Works with WebCrypt API on Cloudflare Workers._ ```ts @@ -16,10 +18,13 @@ export default { request, { password: "IF4B#t69!WlX$uS22blaxDvzJJ%$vEh%", - cookie: "session", } ); - return webCryptSession.response(`Hello ${webCryptSession.session.username}`) + return new Response(`Hello ${webCryptSession.username}`, { + headers: { + "Set-Cookie": webCryptSession.toHeaderValue(), + }, + }); }, }; ``` diff --git a/packages/webcrypt-session/src/adapters/trpc/index.ts b/packages/webcrypt-session/src/adapters/trpc/index.ts index 3aa8f35..5d26121 100644 --- a/packages/webcrypt-session/src/adapters/trpc/index.ts +++ b/packages/webcrypt-session/src/adapters/trpc/index.ts @@ -38,7 +38,7 @@ export async function getWebCryptSession( // Block calls to WebCryptSession's internal functions // allowing access only to the scheme. - return (webCryptSession as unknown) as Exclude< + return (webCryptSession as unknown) as Omit< WebCryptSession, "toHeaderValue" >;