-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
commit session early for remix requests
- Loading branch information
Showing
9 changed files
with
216 additions
and
11 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
import { debuglog } from 'node:util' | ||
|
||
export default debuglog('matstack:remix-adonisjs') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
import type { HttpContext } from '@adonisjs/core/http' | ||
import type { CookieOptions } from '@adonisjs/core/types/http' | ||
|
||
import { SessionData, SessionStoreContract } from '@adonisjs/session/types' | ||
import debug from '../src/debug.js' | ||
|
||
/** | ||
* Cookie store stores the session data inside an encrypted | ||
* cookie. | ||
*/ | ||
export class CookieStore implements SessionStoreContract { | ||
#ctx: HttpContext | ||
#config: Partial<CookieOptions> | ||
|
||
constructor(config: Partial<CookieOptions>, ctx: HttpContext) { | ||
this.#config = config | ||
this.#ctx = ctx | ||
debug('initiating cookie store %O', this.#config) | ||
} | ||
|
||
/** | ||
* Read session value from the cookie | ||
*/ | ||
read(sessionId: string): SessionData | null { | ||
debug('cookie store: reading session data %s', sessionId) | ||
|
||
const cookieValue = this.#ctx.request.encryptedCookie(sessionId) | ||
if (typeof cookieValue !== 'object') { | ||
return null | ||
} | ||
|
||
return cookieValue | ||
} | ||
|
||
/** | ||
* Write session values to the cookie | ||
*/ | ||
write(sessionId: string, values: SessionData): void { | ||
debug('cookie store: writing session data %s: %O', sessionId, values) | ||
this.#ctx.response.encryptedCookie(sessionId, values, this.#config) | ||
} | ||
|
||
/** | ||
* Removes the session cookie | ||
*/ | ||
destroy(sessionId: string): void { | ||
debug('cookie store: destroying session data %s', sessionId) | ||
if (this.#ctx.request.cookiesList()[sessionId]) { | ||
this.#ctx.response.clearCookie(sessionId) | ||
} | ||
} | ||
|
||
/** | ||
* Updates the cookie with existing cookie values | ||
*/ | ||
touch(sessionId: string): void { | ||
const value = this.read(sessionId) | ||
debug('cookie store: touching session data %s', sessionId) | ||
if (!value) { | ||
return | ||
} | ||
|
||
this.write(sessionId, value) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import { test } from '@japa/runner' | ||
import { redirect } from '@remix-run/node' | ||
import setCookieParser from 'set-cookie-parser' | ||
import supertest from 'supertest' | ||
import { cookieClient, remixHandler } from './http_server.js' | ||
|
||
test.group('Session', () => { | ||
test('commit session early for remix request', async ({ assert }) => { | ||
let sessionId: string | undefined | ||
|
||
const remixServer = remixHandler(async (_request, context) => { | ||
const session = context?.http.session | ||
session?.flash('status', 'Completed') | ||
session?.put('username', 'jarle') | ||
sessionId = session?.sessionId | ||
return redirect('/admin') | ||
}) | ||
|
||
const { headers } = await supertest(remixServer).get('/') | ||
|
||
const cookies = setCookieParser.parse(headers['set-cookie'], { map: true }) | ||
assert.deepEqual(cookieClient.decrypt(sessionId!, cookies[sessionId!].value), { | ||
username: 'jarle', | ||
__flash__: { | ||
status: 'Completed', | ||
}, | ||
}) | ||
}) | ||
}) |
29 changes: 29 additions & 0 deletions
29
packages/reference-app/resources/remix_app/routes/login.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import { ActionFunctionArgs, redirect } from '@remix-run/node' | ||
import { Form } from '@remix-run/react' | ||
|
||
export const action = async ({ context }: ActionFunctionArgs) => { | ||
const { http } = context | ||
|
||
http.session.put('login', 'true') | ||
|
||
return redirect('/dashboard') | ||
} | ||
|
||
export default function Page() { | ||
return ( | ||
<div className="container"> | ||
<h1>Log in</h1> | ||
<Form method="post"> | ||
<label> | ||
<input type="email" name="email" /> | ||
</label> | ||
<label> | ||
Password | ||
<input type="password" name="password" /> | ||
</label> | ||
<button type="submit">Login</button> | ||
</Form> | ||
</div> | ||
) | ||
} |