-
Notifications
You must be signed in to change notification settings - Fork 355
feat(session): support password rotation via Record<string, string> #1335
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -29,8 +29,13 @@ export interface SessionManager<T extends SessionDataT = SessionDataT> { | |||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| export interface SessionConfig { | ||||||||||||||||||||||||||||||||||||||
| /** Private key used to encrypt session tokens */ | ||||||||||||||||||||||||||||||||||||||
| password: string; | ||||||||||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||||||||||
| * Private key used to encrypt session tokens. | ||||||||||||||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||||||||||||||
| * For password rotation, pass a record of `{ id: password }` pairs. | ||||||||||||||||||||||||||||||||||||||
| * The first key is used for sealing new sessions, all keys are tried for unsealing. | ||||||||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||||||
| password: string | Record<string, string>; | ||||||||||||||||||||||||||||||||||||||
| /** Session expiration time in seconds */ | ||||||||||||||||||||||||||||||||||||||
| maxAge?: number; | ||||||||||||||||||||||||||||||||||||||
| /** default is h3 */ | ||||||||||||||||||||||||||||||||||||||
|
|
@@ -200,7 +205,12 @@ export async function sealSession<T extends SessionData = SessionData>( | |||||||||||||||||||||||||||||||||||||
| const session: Session<T> = | ||||||||||||||||||||||||||||||||||||||
| (context.sessions?.[sessionName] as Session<T>) || (await getSession<T>(event, config)); | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| const sealed = await seal(session, config.password, { | ||||||||||||||||||||||||||||||||||||||
| const sealPassword = | ||||||||||||||||||||||||||||||||||||||
| typeof config.password === "string" | ||||||||||||||||||||||||||||||||||||||
| ? config.password | ||||||||||||||||||||||||||||||||||||||
| : { id: Object.keys(config.password)[0], secret: Object.values(config.password)[0] }; | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| const sealed = await seal(session, sealPassword, { | ||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+208
to
+213
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Missing validation for empty password record. If 🛡️ Proposed fix to add validation const sealPassword =
typeof config.password === "string"
? config.password
- : { id: Object.keys(config.password)[0], secret: Object.values(config.password)[0] };
+ : (() => {
+ const keys = Object.keys(config.password);
+ if (keys.length === 0) {
+ throw new Error("Password record cannot be empty");
+ }
+ return { id: keys[0], secret: config.password[keys[0]] };
+ })();Alternatively, use a simpler approach with const sealPassword =
typeof config.password === "string"
? config.password
- : { id: Object.keys(config.password)[0], secret: Object.values(config.password)[0] };
+ : (() => {
+ const [[id, secret]] = Object.entries(config.password);
+ if (!id) throw new Error("Password record cannot be empty");
+ return { id, secret };
+ })();📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||
| ...sealDefaults, | ||||||||||||||||||||||||||||||||||||||
| ttl: config.maxAge ? config.maxAge * 1000 : 0, | ||||||||||||||||||||||||||||||||||||||
| ...config.seal, | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we are only takin first!