From 096c9c0276b88fa206552e49707f20a964828828 Mon Sep 17 00:00:00 2001
From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com>
Date: Fri, 11 Oct 2024 15:21:43 -0400
Subject: [PATCH 01/18] update mode
---
packages/adders/lucia/index.ts | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/packages/adders/lucia/index.ts b/packages/adders/lucia/index.ts
index 5a6c40207..982393a12 100644
--- a/packages/adders/lucia/index.ts
+++ b/packages/adders/lucia/index.ts
@@ -133,7 +133,9 @@ export default defineAdder({
userId: common.expressionFromString(
`text('user_id').notNull().references(() => user.id)`
),
- expiresAt: common.expressionFromString(`integer('expires_at').notNull()`)
+ expiresAt: common.expressionFromString(
+ `integer('expires_at', { mode: 'timestamp' }).notNull()`
+ )
});
}
if (drizzleDialect === 'mysql') {
From 6c29fc44e2951c72d65eaaa695c659d176822ba0 Mon Sep 17 00:00:00 2001
From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com>
Date: Sat, 12 Oct 2024 13:53:06 -0400
Subject: [PATCH 02/18] partial auth impl
---
packages/adders/lucia/index.ts | 195 ++++++++++++++++++++++-----------
1 file changed, 134 insertions(+), 61 deletions(-)
diff --git a/packages/adders/lucia/index.ts b/packages/adders/lucia/index.ts
index 982393a12..0c6ac9787 100644
--- a/packages/adders/lucia/index.ts
+++ b/packages/adders/lucia/index.ts
@@ -2,22 +2,16 @@ import { colors, dedent, defineAdder, defineAdderOptions, log, Walker } from '@s
import { common, exports, imports, variables, object, functions } from '@sveltejs/cli-core/js';
// eslint-disable-next-line no-duplicate-imports
import type { AstTypes } from '@sveltejs/cli-core/js';
-import { addHooksHandle, addGlobalAppInterface, hasTypeProp } from '../common.ts';
+import { addHooksHandle, addGlobalAppInterface, hasTypeProp, createPrinter } from '../common.ts';
import { parseScript } from '@sveltejs/cli-core/parsers';
-const LUCIA_ADAPTER = {
- mysql: 'DrizzleMySQLAdapter',
- postgresql: 'DrizzlePostgreSQLAdapter',
- sqlite: 'DrizzleSQLiteAdapter'
-} as const;
-
const TABLE_TYPE = {
mysql: 'mysqlTable',
postgresql: 'pgTable',
sqlite: 'sqliteTable'
};
-type Dialect = keyof typeof LUCIA_ADAPTER;
+type Dialect = 'mysql' | 'postgresql' | 'sqlite';
let drizzleDialect: Dialect;
let schemaPath: string;
@@ -38,8 +32,8 @@ export default defineAdder({
documentation: 'https://lucia-auth.com',
options,
packages: [
- { name: 'lucia', version: '^3.2.0', dev: false },
- { name: '@lucia-auth/adapter-drizzle', version: '^1.1.0', dev: false },
+ { name: '@oslojs/crypto', version: '^1.0.1', dev: false },
+ { name: '@oslojs/encoding', version: '^1.1.0', dev: false },
// password hashing for demo
{
name: '@node-rs/argon2',
@@ -195,47 +189,125 @@ export default defineAdder({
},
{
name: ({ kit, typescript }) => `${kit?.libDirectory}/server/auth.${typescript ? 'ts' : 'js'}`,
- content: ({ content, typescript, options }) => {
+ content: ({ content, typescript }) => {
const { ast, generateCode } = parseScript(content);
- const adapter = LUCIA_ADAPTER[drizzleDialect];
- imports.addNamed(ast, '$lib/server/db/schema.js', { user: 'user', session: 'session' });
+ imports.addNamespace(content, '$lib/server/db/schema', 'table');
imports.addNamed(ast, '$lib/server/db', { db: 'db' });
- imports.addNamed(ast, 'lucia', { Lucia: 'Lucia' });
- imports.addNamed(ast, '@lucia-auth/adapter-drizzle', { [adapter]: adapter });
- imports.addNamed(ast, '$app/environment', { dev: 'dev' });
+ imports.addNamed(ast, '@oslojs/encoding', {
+ encodeBase32LowerCaseNoPadding: 'encodeBase32LowerCaseNoPadding',
+ encodeHexLowerCase: 'encodeHexLowerCase'
+ });
+ imports.addNamed(ast, '@oslojs/crypto/random', {
+ generateRandomString: 'generateRandomString'
+ });
+ imports.addNamed(ast, '@oslojs/crypto/random', { RandomReader: 'RandomReader' }, true);
+ imports.addNamed(ast, '@oslojs/crypto/sha2', { sha256: 'sha256' });
+ imports.addNamed(ast, 'drizzle-orm', { eq: 'eq' });
+
+ common.addFromString(ast, 'const DAY_IN_MS = 1000 * 60 * 60 * 24;');
+
+ const cookieName = common.createLiteral('auth-session');
+ const session = variables.declaration(ast, 'const', 'sessionCookieName', cookieName);
+ exports.namedExport(ast, 'sessionCookieName', session);
+
+ const [ts] = createPrinter(typescript);
+ common.addFromString(
+ ast,
+ `
+ function generateSessionToken()${ts(': string')} {
+ const bytes = crypto.getRandomValues(new Uint8Array(20));
+ const token = encodeBase32LowerCaseNoPadding(bytes);
+ return token;
+ }
+ `
+ );
+ common.addFromString(
+ ast,
+ `
+ const random${ts(': RandomReader')} = {
+ read(bytes${ts(': Uint8Array')})${ts(': void')} {
+ crypto.getRandomValues(bytes);
+ }
+ };
+ `
+ );
+ common.addFromString(
+ ast,
+ `
+ export function generateId(length${ts(': number')})${ts(': string')} {
+ const alphabet = 'abcdefghijklmnopqrstuvwxyz0123456789';
+ return generateRandomString(random, alphabet, length);
+ }`
+ );
+ common.addFromString(
+ ast,
+ `
+ export async function createSession(userId${ts(': string')})${ts(': Promise
')} {
+ const token = generateSessionToken();
+ const sessionId = encodeHexLowerCase(sha256(new TextEncoder().encode(token)));
+ const session${ts(': table.Session')} = {
+ id: sessionId,
+ userId,
+ expiresAt: new Date(Date.now() + DAY_IN_MS * 30)
+ };
+ await db.insert(table.session).values(session);
+ return session;
+ }`
+ );
+ common.addFromString(
+ ast,
+ `
+ export async function validateSession(sessionId${ts(': string')})${ts(': Promise')} {
+ const [result] = await db
+ .select({
+ // Adjust user table here to tweak returned data
+ user: { id: table.user.id, username: table.user.username },
+ session: table.session
+ })
+ .from(table.session)
+ .innerJoin(table.user, eq(table.session.userId, table.user.id))
+ .where(eq(table.session.id, sessionId));
+
+ if (!result) {
+ return { session: null, user: null };
+ }
+ const { session, user } = result;
- // adapter
- const adapterDecl = common.statementFromString(
- `const adapter = new ${adapter}(db, session, user);`
+ const sessionExpired = Date.now() >= session.expiresAt.getTime();
+ if (sessionExpired) {
+ await db.delete(table.session).where(eq(table.session.id, session.id));
+ return { session: null, user: null };
+ }
+
+ const renewSession = Date.now() >= session.expiresAt.getTime() - DAY_IN_MS * 15;
+ if (renewSession) {
+ session.expiresAt = new Date(Date.now() + DAY_IN_MS * 30);
+ await db
+ .update(table.session)
+ .set({ expiresAt: session.expiresAt })
+ .where(eq(table.session.id, session.id));
+ }
+
+ return { session, user };
+ }`
);
- common.addStatement(ast, adapterDecl);
-
- // lucia export
- const luciaInit = common.expressionFromString(`
- new Lucia(adapter, {
- sessionCookie: {
- attributes: {
- secure: !dev
- }
- },
- ${options.demo ? 'getUserAttributes: (attributes) => ({ username: attributes.username })' : ''}
- })`);
- const luciaDecl = variables.declaration(ast, 'const', 'lucia', luciaInit);
- exports.namedExport(ast, 'lucia', luciaDecl);
-
- // module declaration
- if (typescript && !/declare module ["']lucia["']/.test(content)) {
- const moduleDecl = common.statementFromString(`
- declare module 'lucia' {
- interface Register {
- Lucia: typeof lucia;
- // attributes that are already included are omitted
- DatabaseUserAttributes: Omit;
- DatabaseSessionAttributes: Omit;
- }
- }`);
- common.addStatement(ast, moduleDecl);
+ common.addFromString(
+ ast,
+ `
+ export async function invalidateSession(sessionId${ts(': string')})${ts(': Promise')} {
+ await db.delete(table.session).where(eq(table.session.id, sessionId));
+ }`
+ );
+
+ // exports validation type
+ if (typescript && !content.includes('export type SessionValidationResult')) {
+ const validatedSessionType = common.statementFromString(`
+ export type SessionValidationResult =
+ | { session: table.Session; user: Omit }
+ | { session: null; user: null };
+ `);
+ common.addStatement(ast, validatedSessionType);
}
return generateCode();
}
@@ -286,7 +358,7 @@ export default defineAdder({
return content;
}
- const ts = (str: string, opt = '') => (typescript ? str : opt);
+ const [ts] = createPrinter(typescript);
return dedent`
import { fail, redirect } from '@sveltejs/kit';
import { hash, verify } from '@node-rs/argon2';
@@ -547,21 +619,22 @@ function createLuciaType(name: string): AstTypes.TSInterfaceBody['body'][number]
typeAnnotation: {
type: 'TSTypeAnnotation',
typeAnnotation: {
- type: 'TSUnionType',
- types: [
- {
- type: 'TSImportType',
- argument: { type: 'StringLiteral', value: 'lucia' },
- qualifier: {
- type: 'Identifier',
- // capitalize first letter
- name: `${name[0]!.toUpperCase()}${name.slice(1)}`
- }
- },
- {
- type: 'TSNullKeyword'
+ type: 'TSIndexedAccessType',
+ objectType: {
+ type: 'TSImportType',
+ argument: { type: 'StringLiteral', value: '$lib/server/auth' },
+ qualifier: {
+ type: 'Identifier',
+ name: 'SessionValidationResult'
+ }
+ },
+ indexType: {
+ type: 'TSLiteralType',
+ literal: {
+ type: 'StringLiteral',
+ value: name
}
- ]
+ }
}
}
};
From 7898a058ba0a683be676271bef7e57542e2ad99a Mon Sep 17 00:00:00 2001
From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com>
Date: Sat, 12 Oct 2024 13:54:12 -0400
Subject: [PATCH 03/18] add namespace import
---
packages/adders/lucia/index.ts | 2 +-
packages/core/tooling/js/imports.ts | 15 +++++++++++++++
2 files changed, 16 insertions(+), 1 deletion(-)
diff --git a/packages/adders/lucia/index.ts b/packages/adders/lucia/index.ts
index 0c6ac9787..6f3ef44ab 100644
--- a/packages/adders/lucia/index.ts
+++ b/packages/adders/lucia/index.ts
@@ -192,7 +192,7 @@ export default defineAdder({
content: ({ content, typescript }) => {
const { ast, generateCode } = parseScript(content);
- imports.addNamespace(content, '$lib/server/db/schema', 'table');
+ imports.addNamespace(ast, '$lib/server/db/schema', 'table');
imports.addNamed(ast, '$lib/server/db', { db: 'db' });
imports.addNamed(ast, '@oslojs/encoding', {
encodeBase32LowerCaseNoPadding: 'encodeBase32LowerCaseNoPadding',
diff --git a/packages/core/tooling/js/imports.ts b/packages/core/tooling/js/imports.ts
index 7abd01ad9..3f6b70ece 100644
--- a/packages/core/tooling/js/imports.ts
+++ b/packages/core/tooling/js/imports.ts
@@ -14,6 +14,21 @@ export function addEmpty(ast: AstTypes.Program, importFrom: string): void {
addImportIfNecessary(ast, expectedImportDeclaration);
}
+export function addNamespace(ast: AstTypes.Program, importFrom: string, importAs: string): string {
+ const expectedImportDeclaration: AstTypes.ImportDeclaration = {
+ type: 'ImportDeclaration',
+ source: { type: 'Literal', value: importFrom },
+ specifiers: [
+ {
+ type: 'ImportNamespaceSpecifier',
+ local: { type: 'Identifier', name: importAs }
+ }
+ ]
+ };
+
+ addImportIfNecessary(ast, expectedImportDeclaration);
+}
+
export function addDefault(ast: AstTypes.Program, importFrom: string, importAs: string): void {
const expectedImportDeclaration: AstTypes.ImportDeclaration = {
type: 'ImportDeclaration',
From b1f72e6ebd758662061b614f3d28145f68997939 Mon Sep 17 00:00:00 2001
From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com>
Date: Sat, 12 Oct 2024 14:01:10 -0400
Subject: [PATCH 04/18] add test
---
.../core/tests/js/imports/namespaced-import/output.ts | 2 ++
packages/core/tests/js/imports/namespaced-import/run.ts | 9 +++++++++
packages/core/tooling/js/imports.ts | 2 +-
3 files changed, 12 insertions(+), 1 deletion(-)
create mode 100644 packages/core/tests/js/imports/namespaced-import/output.ts
create mode 100644 packages/core/tests/js/imports/namespaced-import/run.ts
diff --git a/packages/core/tests/js/imports/namespaced-import/output.ts b/packages/core/tests/js/imports/namespaced-import/output.ts
new file mode 100644
index 000000000..ca6f2f5b3
--- /dev/null
+++ b/packages/core/tests/js/imports/namespaced-import/output.ts
@@ -0,0 +1,2 @@
+import * as bar from "./some-file";
+import * as foo from "package";
\ No newline at end of file
diff --git a/packages/core/tests/js/imports/namespaced-import/run.ts b/packages/core/tests/js/imports/namespaced-import/run.ts
new file mode 100644
index 000000000..f46a38afc
--- /dev/null
+++ b/packages/core/tests/js/imports/namespaced-import/run.ts
@@ -0,0 +1,9 @@
+import { imports, type AstTypes } from '@sveltejs/cli-core/js';
+
+export function run({ ast }: { ast: AstTypes.Program }): void {
+ imports.addNamespace(ast, 'package', 'foo');
+
+ imports.addNamespace(ast, './some-file', 'bar');
+ // adding the same import twice should not produce two imports
+ imports.addNamespace(ast, './some-file', 'bar');
+}
diff --git a/packages/core/tooling/js/imports.ts b/packages/core/tooling/js/imports.ts
index 3f6b70ece..a0dd0fcf5 100644
--- a/packages/core/tooling/js/imports.ts
+++ b/packages/core/tooling/js/imports.ts
@@ -14,7 +14,7 @@ export function addEmpty(ast: AstTypes.Program, importFrom: string): void {
addImportIfNecessary(ast, expectedImportDeclaration);
}
-export function addNamespace(ast: AstTypes.Program, importFrom: string, importAs: string): string {
+export function addNamespace(ast: AstTypes.Program, importFrom: string, importAs: string): void {
const expectedImportDeclaration: AstTypes.ImportDeclaration = {
type: 'ImportDeclaration',
source: { type: 'Literal', value: importFrom },
From fc8b903d101726b3d8d76f3fbf30daca1206762b Mon Sep 17 00:00:00 2001
From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com>
Date: Sat, 12 Oct 2024 14:39:33 -0400
Subject: [PATCH 05/18] replace with a coarser approach for now
---
packages/adders/lucia/index.ts | 121 ++++++++++++---------------------
1 file changed, 42 insertions(+), 79 deletions(-)
diff --git a/packages/adders/lucia/index.ts b/packages/adders/lucia/index.ts
index 6f3ef44ab..7d767aea6 100644
--- a/packages/adders/lucia/index.ts
+++ b/packages/adders/lucia/index.ts
@@ -189,60 +189,36 @@ export default defineAdder({
},
{
name: ({ kit, typescript }) => `${kit?.libDirectory}/server/auth.${typescript ? 'ts' : 'js'}`,
- content: ({ content, typescript }) => {
- const { ast, generateCode } = parseScript(content);
-
- imports.addNamespace(ast, '$lib/server/db/schema', 'table');
- imports.addNamed(ast, '$lib/server/db', { db: 'db' });
- imports.addNamed(ast, '@oslojs/encoding', {
- encodeBase32LowerCaseNoPadding: 'encodeBase32LowerCaseNoPadding',
- encodeHexLowerCase: 'encodeHexLowerCase'
- });
- imports.addNamed(ast, '@oslojs/crypto/random', {
- generateRandomString: 'generateRandomString'
- });
- imports.addNamed(ast, '@oslojs/crypto/random', { RandomReader: 'RandomReader' }, true);
- imports.addNamed(ast, '@oslojs/crypto/sha2', { sha256: 'sha256' });
- imports.addNamed(ast, 'drizzle-orm', { eq: 'eq' });
+ content: ({ content, typescript, kit }) => {
+ if (content) {
+ const filePath = `${kit!.libDirectory}/server/auth.${typescript ? 'ts' : 'js'}`;
+ log.warn(`Existing ${colors.yellow(filePath)} file. Could not update.`);
+ return content;
+ }
+ const [ts] = createPrinter(typescript);
+ return dedent`
+ import { eq } from 'drizzle-orm';
+ import { sha256 } from '@oslojs/crypto/sha2';
+ import { generateRandomString } from '@oslojs/crypto/random';
+ import { encodeBase32LowerCaseNoPadding, encodeHexLowerCase } from '@oslojs/encoding';
+ import { db } from '$lib/server/db';
+ import * as table from '$lib/server/db/schema';
- common.addFromString(ast, 'const DAY_IN_MS = 1000 * 60 * 60 * 24;');
+ const DAY_IN_MS = 1000 * 60 * 60 * 24;
- const cookieName = common.createLiteral('auth-session');
- const session = variables.declaration(ast, 'const', 'sessionCookieName', cookieName);
- exports.namedExport(ast, 'sessionCookieName', session);
+ export const sessionCookieName = 'auth-session';
- const [ts] = createPrinter(typescript);
- common.addFromString(
- ast,
- `
function generateSessionToken()${ts(': string')} {
const bytes = crypto.getRandomValues(new Uint8Array(20));
const token = encodeBase32LowerCaseNoPadding(bytes);
return token;
}
- `
- );
- common.addFromString(
- ast,
- `
- const random${ts(': RandomReader')} = {
- read(bytes${ts(': Uint8Array')})${ts(': void')} {
- crypto.getRandomValues(bytes);
- }
- };
- `
- );
- common.addFromString(
- ast,
- `
+
export function generateId(length${ts(': number')})${ts(': string')} {
const alphabet = 'abcdefghijklmnopqrstuvwxyz0123456789';
- return generateRandomString(random, alphabet, length);
- }`
- );
- common.addFromString(
- ast,
- `
+ return generateRandomString({ read: (bytes) => crypto.getRandomValues(bytes) }, alphabet, length);
+ }
+
export async function createSession(userId${ts(': string')})${ts(': Promise')} {
const token = generateSessionToken();
const sessionId = encodeHexLowerCase(sha256(new TextEncoder().encode(token)));
@@ -253,11 +229,12 @@ export default defineAdder({
};
await db.insert(table.session).values(session);
return session;
- }`
- );
- common.addFromString(
- ast,
- `
+ }
+
+ ${ts('export type SessionValidationResult =')}
+ ${ts("| { session: table.Session; user: Omit }")}
+ ${ts('| { session: null; user: null };')}
+
export async function validateSession(sessionId${ts(': string')})${ts(': Promise')} {
const [result] = await db
.select({
@@ -290,26 +267,12 @@ export default defineAdder({
}
return { session, user };
- }`
- );
- common.addFromString(
- ast,
- `
+ }
+
export async function invalidateSession(sessionId${ts(': string')})${ts(': Promise')} {
await db.delete(table.session).where(eq(table.session.id, sessionId));
- }`
- );
-
- // exports validation type
- if (typescript && !content.includes('export type SessionValidationResult')) {
- const validatedSessionType = common.statementFromString(`
- export type SessionValidationResult =
- | { session: table.Session; user: Omit }
- | { session: null; user: null };
- `);
- common.addStatement(ast, validatedSessionType);
- }
- return generateCode();
+ }
+ `;
}
},
{
@@ -350,11 +313,10 @@ export default defineAdder({
name: ({ kit, typescript }) =>
`${kit!.routesDirectory}/demo/login/+page.server.${typescript ? 'ts' : 'js'}`,
condition: ({ options }) => options.demo,
- content({ content, typescript }) {
+ content({ content, typescript, kit }) {
if (content) {
- log.warn(
- `Existing ${colors.yellow('/demo/login/+page.server.[js|ts]')} file. Could not update.`
- );
+ const filePath = `${kit!.routesDirectory}/demo/login/+page.server.${typescript ? 'ts' : 'js'}`;
+ log.warn(`Existing ${colors.yellow(filePath)} file. Could not update.`);
return content;
}
@@ -495,9 +457,10 @@ export default defineAdder({
{
name: ({ kit }) => `${kit!.routesDirectory}/demo/login/+page.svelte`,
condition: ({ options }) => options.demo,
- content({ content, typescript }) {
+ content({ content, typescript, kit }) {
if (content) {
- log.warn(`Existing ${colors.yellow('/demo/login/+page.svelte')} file. Could not update.`);
+ const filePath = `${kit!.routesDirectory}/demo/login/+page.svelte`;
+ log.warn(`Existing ${colors.yellow(filePath)} file. Could not update.`);
return content;
}
@@ -532,11 +495,10 @@ export default defineAdder({
name: ({ kit, typescript }) =>
`${kit!.routesDirectory}/demo/+page.server.${typescript ? 'ts' : 'js'}`,
condition: ({ options }) => options.demo,
- content({ content, typescript }) {
+ content({ content, typescript, kit }) {
if (content) {
- log.warn(
- `Existing ${colors.yellow('/demo/+page.server.[js|ts]')} file. Could not update.`
- );
+ const filePath = `${kit!.routesDirectory}/demo/+page.server.${typescript ? 'ts' : 'js'}`;
+ log.warn(`Existing ${colors.yellow(filePath)} file. Could not update.`);
return content;
}
@@ -575,9 +537,10 @@ export default defineAdder({
{
name: ({ kit }) => `${kit!.routesDirectory}/demo/+page.svelte`,
condition: ({ options }) => options.demo,
- content({ content, typescript }) {
+ content({ content, typescript, kit }) {
if (content) {
- log.warn(`Existing ${colors.yellow('/demo/+page.svelte')} file. Could not update.`);
+ const filePath = `${kit!.routesDirectory}/demo/+page.svelte`;
+ log.warn(`Existing ${colors.yellow(filePath)} file. Could not update.`);
return content;
}
From 967548ade49955babfed1c9b15057108d0df83fa Mon Sep 17 00:00:00 2001
From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com>
Date: Sat, 12 Oct 2024 15:49:51 -0400
Subject: [PATCH 06/18] simplify
---
packages/adders/lucia/index.ts | 16 ++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)
diff --git a/packages/adders/lucia/index.ts b/packages/adders/lucia/index.ts
index 7d767aea6..d03407506 100644
--- a/packages/adders/lucia/index.ts
+++ b/packages/adders/lucia/index.ts
@@ -184,7 +184,14 @@ export default defineAdder({
)
});
}
- return generateCode();
+ let code = generateCode();
+ if (!code.includes('export type Session =')) {
+ code += '\n\nexport type Session = typeof session.$inferSelect;';
+ }
+ if (!code.includes('export type User =')) {
+ code += '\n\nexport type User = typeof user.$inferSelect;';
+ }
+ return code;
}
},
{
@@ -231,11 +238,8 @@ export default defineAdder({
return session;
}
- ${ts('export type SessionValidationResult =')}
- ${ts("| { session: table.Session; user: Omit }")}
- ${ts('| { session: null; user: null };')}
-
- export async function validateSession(sessionId${ts(': string')})${ts(': Promise')} {
+ ${ts('export type SessionValidationResult = Awaited>;\n')}
+ export async function validateSession(sessionId${ts(': string')}) {
const [result] = await db
.select({
// Adjust user table here to tweak returned data
From 44e1791f6749424b8f95ff285702a9b72e0383d3 Mon Sep 17 00:00:00 2001
From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com>
Date: Sat, 12 Oct 2024 15:53:15 -0400
Subject: [PATCH 07/18] update hooks
---
packages/adders/lucia/index.ts | 21 ++++++++++-----------
1 file changed, 10 insertions(+), 11 deletions(-)
diff --git a/packages/adders/lucia/index.ts b/packages/adders/lucia/index.ts
index d03407506..05cd0facb 100644
--- a/packages/adders/lucia/index.ts
+++ b/packages/adders/lucia/index.ts
@@ -306,7 +306,7 @@ export default defineAdder({
name: ({ typescript }) => `src/hooks.server.${typescript ? 'ts' : 'js'}`,
content: ({ content, typescript }) => {
const { ast, generateCode } = parseScript(content);
- imports.addNamed(ast, '$lib/server/auth.js', { lucia: 'lucia' });
+ imports.addNamespace(ast, '$lib/server/auth.js', 'auth');
addHooksHandle(ast, typescript, 'auth', getAuthHandleContent());
return generateCode();
}
@@ -610,25 +610,24 @@ function createLuciaType(name: string): AstTypes.TSInterfaceBody['body'][number]
function getAuthHandleContent() {
return `
async ({ event, resolve }) => {
- const sessionId = event.cookies.get(lucia.sessionCookieName);
+ const sessionId = event.cookies.get(auth.sessionCookieName);
if (!sessionId) {
event.locals.user = null;
event.locals.session = null;
return resolve(event);
}
- const { session, user } = await lucia.validateSession(sessionId);
+ const { session, user } = await auth.validateSession(sessionId);
if (!session) {
- event.cookies.delete(lucia.sessionCookieName, { path: '/' });
- }
-
- if (session?.fresh) {
- const sessionCookie = lucia.createSessionCookie(session.id);
-
- event.cookies.set(sessionCookie.name, sessionCookie.value, {
+ event.cookies.set(auth.sessionCookieName, session.id, {
path: '/',
- ...sessionCookie.attributes,
+ sameSite: 'lax',
+ httpOnly: true,
+ expires: session.expiresAt,
+ secure: !dev
});
+ } else {
+ event.cookies.delete(auth.sessionCookieName, { path: '/' });
}
event.locals.user = user;
From 033b9a2fb9ad428ca38ca31a8c24a65249c5bf52 Mon Sep 17 00:00:00 2001
From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com>
Date: Sat, 12 Oct 2024 16:04:03 -0400
Subject: [PATCH 08/18] update demo
---
packages/adders/lucia/index.ts | 81 +++++++++++++---------------------
1 file changed, 31 insertions(+), 50 deletions(-)
diff --git a/packages/adders/lucia/index.ts b/packages/adders/lucia/index.ts
index 05cd0facb..424b6e108 100644
--- a/packages/adders/lucia/index.ts
+++ b/packages/adders/lucia/index.ts
@@ -330,9 +330,9 @@ export default defineAdder({
import { hash, verify } from '@node-rs/argon2';
import { eq } from 'drizzle-orm';
import { generateId } from 'lucia';
- import { lucia } from '$lib/server/auth';
import { db } from '$lib/server/db';
- import { user } from '$lib/server/db/schema.js';
+ import * as auth from '$lib/server/auth';
+ import * as table from '$lib/server/db/schema';
${ts(`import type { Actions, PageServerLoad } from './$types';`)}
export const load${ts(': PageServerLoad')} = async (event) => {
@@ -349,26 +349,20 @@ export default defineAdder({
const password = formData.get('password');
if (!validateUsername(username)) {
- return fail(400, {
- message: 'Invalid username',
- });
+ return fail(400, { message: 'Invalid username' });
}
if (!validatePassword(password)) {
- return fail(400, {
- message: 'Invalid password',
- });
+ return fail(400, { message: 'Invalid password' });
}
const results = await db
.select()
.from(user)
- .where(eq(user.username, username));
+ .where(eq(table.user.username, username));
const existingUser = results.at(0);
if (!existingUser) {
- return fail(400, {
- message: 'Incorrect username or password',
- });
+ return fail(400, { message: 'Incorrect username or password' });
}
const validPassword = await verify(existingUser.passwordHash, password, {
@@ -378,16 +372,16 @@ export default defineAdder({
parallelism: 1,
});
if (!validPassword) {
- return fail(400, {
- message: 'Incorrect username or password',
- });
+ return fail(400, { message: 'Incorrect username or password' });
}
- const session = await lucia.createSession(existingUser.id, {});
- const sessionCookie = lucia.createSessionCookie(session.id);
- event.cookies.set(sessionCookie.name, sessionCookie.value, {
+ const session = await auth.createSession(existingUser.id);
+ event.cookies.set(auth.sessionCookieName, session.id, {
path: '/',
- ...sessionCookie.attributes,
+ sameSite: 'lax',
+ httpOnly: true,
+ expires: session.expiresAt,
+ secure: !dev
});
return redirect(302, '/demo');
@@ -398,16 +392,13 @@ export default defineAdder({
const password = formData.get('password');
if (!validateUsername(username)) {
- return fail(400, {
- message: 'Invalid username',
- });
+ return fail(400, { message: 'Invalid username' });
}
if (!validatePassword(password)) {
- return fail(400, {
- message: 'Invalid password',
- });
+ return fail(400, { message: 'Invalid password' });
}
+ const userId = generateId(15);
const passwordHash = await hash(password, {
// recommended minimum parameters
memoryCost: 19456,
@@ -415,31 +406,26 @@ export default defineAdder({
outputLen: 32,
parallelism: 1,
});
- const userId = generateId(15);
try {
- await db.insert(user).values({
- id: userId,
- username,
- passwordHash,
- });
+ await db.insert(user).values({ id: userId, username, passwordHash });
- const session = await lucia.createSession(userId, {});
- const sessionCookie = lucia.createSessionCookie(session.id);
- event.cookies.set(sessionCookie.name, sessionCookie.value, {
+ const session = await auth.createSession(userId);
+ event.cookies.set(auth.sessionCookieName, session.id, {
path: '/',
- ...sessionCookie.attributes,
+ sameSite: 'lax',
+ httpOnly: true,
+ expires: session.expiresAt,
+ secure: !dev
});
} catch (e) {
- return fail(500, {
- message: 'An error has occurred',
- });
+ return fail(500, { message: 'An error has occurred' });
}
return redirect(302, '/demo');
},
};
- function validateUsername(username${ts(': unknown): username is string', ')')} {
+ function validateUsername(username${ts(': unknown')})${ts(': username is string')} {
return (
typeof username === 'string' &&
username.length >= 3 &&
@@ -448,7 +434,7 @@ export default defineAdder({
);
}
- function validatePassword(password${ts(': unknown): password is string', ')')} {
+ function validatePassword(password${ts(': unknown')})${ts(': password is string')} {
return (
typeof password === 'string' &&
password.length >= 6 &&
@@ -508,7 +494,7 @@ export default defineAdder({
const ts = (str: string) => (typescript ? str : '');
return dedent`
- import { lucia } from '$lib/server/auth';
+ import * as auth from '$lib/server/auth';
import { fail, redirect } from '@sveltejs/kit';
${ts(`import type { Actions, PageServerLoad } from './$types';`)}
@@ -516,9 +502,7 @@ export default defineAdder({
if (!event.locals.user) {
return redirect(302, '/demo/login');
}
- return {
- user: event.locals.user,
- };
+ return { user: event.locals.user };
};
export const actions${ts(': Actions')} = {
@@ -526,12 +510,9 @@ export default defineAdder({
if (!event.locals.session) {
return fail(401);
}
- await lucia.invalidateSession(event.locals.session.id);
- const sessionCookie = lucia.createBlankSessionCookie();
- event.cookies.set(sessionCookie.name, sessionCookie.value, {
- path: '/',
- ...sessionCookie.attributes,
- });
+ await auth.invalidateSession(event.locals.session.id);
+ event.cookies.delete(auth.sessionCookieName, { path: '/' });
+
return redirect(302, '/demo/login');
},
};
From 6f489c6cee59bd33b1bade7749268d24e05ea641 Mon Sep 17 00:00:00 2001
From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com>
Date: Sat, 12 Oct 2024 16:11:50 -0400
Subject: [PATCH 09/18] fix flags
---
packages/cli/commands/add/index.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/packages/cli/commands/add/index.ts b/packages/cli/commands/add/index.ts
index dca328d92..e2b74455b 100644
--- a/packages/cli/commands/add/index.ts
+++ b/packages/cli/commands/add/index.ts
@@ -27,7 +27,7 @@ const AddersSchema = v.array(v.string());
const AdderOptionFlagsSchema = v.object({
tailwindcss: v.optional(v.array(v.string())),
drizzle: v.optional(v.array(v.string())),
- supabase: v.optional(v.array(v.string()))
+ lucia: v.optional(v.array(v.string()))
});
const OptionsSchema = v.strictObject({
cwd: v.string(),
From 0267d7adcf9d3934b6e8d5109da69adfdeccb45b Mon Sep 17 00:00:00 2001
From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com>
Date: Sat, 12 Oct 2024 16:12:02 -0400
Subject: [PATCH 10/18] update demo code
---
packages/adders/lucia/index.ts | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/packages/adders/lucia/index.ts b/packages/adders/lucia/index.ts
index 424b6e108..8ecffa89b 100644
--- a/packages/adders/lucia/index.ts
+++ b/packages/adders/lucia/index.ts
@@ -326,10 +326,10 @@ export default defineAdder({
const [ts] = createPrinter(typescript);
return dedent`
+ import { dev } from '$app/environment';
import { fail, redirect } from '@sveltejs/kit';
import { hash, verify } from '@node-rs/argon2';
import { eq } from 'drizzle-orm';
- import { generateId } from 'lucia';
import { db } from '$lib/server/db';
import * as auth from '$lib/server/auth';
import * as table from '$lib/server/db/schema';
@@ -357,7 +357,7 @@ export default defineAdder({
const results = await db
.select()
- .from(user)
+ .from(table.user)
.where(eq(table.user.username, username));
const existingUser = results.at(0);
@@ -398,7 +398,7 @@ export default defineAdder({
return fail(400, { message: 'Invalid password' });
}
- const userId = generateId(15);
+ const userId = auth.generateId(15);
const passwordHash = await hash(password, {
// recommended minimum parameters
memoryCost: 19456,
@@ -408,7 +408,7 @@ export default defineAdder({
});
try {
- await db.insert(user).values({ id: userId, username, passwordHash });
+ await db.insert(table.user).values({ id: userId, username, passwordHash });
const session = await auth.createSession(userId);
event.cookies.set(auth.sessionCookieName, session.id, {
@@ -512,7 +512,7 @@ export default defineAdder({
}
await auth.invalidateSession(event.locals.session.id);
event.cookies.delete(auth.sessionCookieName, { path: '/' });
-
+
return redirect(302, '/demo/login');
},
};
From e1c5708a9cbc64b243d0adf1f57275d6876a599e Mon Sep 17 00:00:00 2001
From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com>
Date: Sat, 12 Oct 2024 16:20:16 -0400
Subject: [PATCH 11/18] fix issues
---
packages/adders/lucia/index.ts | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/packages/adders/lucia/index.ts b/packages/adders/lucia/index.ts
index 8ecffa89b..bf410bb7c 100644
--- a/packages/adders/lucia/index.ts
+++ b/packages/adders/lucia/index.ts
@@ -307,6 +307,7 @@ export default defineAdder({
content: ({ content, typescript }) => {
const { ast, generateCode } = parseScript(content);
imports.addNamespace(ast, '$lib/server/auth.js', 'auth');
+ imports.addNamed(ast, '$app/environment', { dev: 'dev' });
addHooksHandle(ast, typescript, 'auth', getAuthHandleContent());
return generateCode();
}
@@ -599,7 +600,7 @@ function getAuthHandleContent() {
}
const { session, user } = await auth.validateSession(sessionId);
- if (!session) {
+ if (session) {
event.cookies.set(auth.sessionCookieName, session.id, {
path: '/',
sameSite: 'lax',
From 0fe55038d148c7dc6b6445ac98eb3b914ce33c5a Mon Sep 17 00:00:00 2001
From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com>
Date: Sat, 12 Oct 2024 16:24:42 -0400
Subject: [PATCH 12/18] go away
---
tsconfig.json | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/tsconfig.json b/tsconfig.json
index 773f62bda..415c0abdc 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -20,7 +20,6 @@
"esModuleInterop": true,
"verbatimModuleSyntax": true,
"isolatedModules": true,
- "noEmit": true,
- "noUncheckedIndexedAccess": true
+ "noEmit": true
}
}
From 5156e8c1a1b1fa8dca073f2829953e6b9c287e34 Mon Sep 17 00:00:00 2001
From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com>
Date: Sun, 13 Oct 2024 13:09:48 -0400
Subject: [PATCH 13/18] dont export type when in js mode
---
packages/adders/lucia/index.ts | 15 +++++++++------
1 file changed, 9 insertions(+), 6 deletions(-)
diff --git a/packages/adders/lucia/index.ts b/packages/adders/lucia/index.ts
index bf410bb7c..3f22f6cb3 100644
--- a/packages/adders/lucia/index.ts
+++ b/packages/adders/lucia/index.ts
@@ -74,7 +74,7 @@ export default defineAdder({
},
{
name: () => schemaPath,
- content: ({ content, options }) => {
+ content: ({ content, options, typescript }) => {
const { ast, generateCode } = parseScript(content);
const createTable = (name: string) => functions.call(TABLE_TYPE[drizzleDialect], [name]);
@@ -184,12 +184,15 @@ export default defineAdder({
)
});
}
+
let code = generateCode();
- if (!code.includes('export type Session =')) {
- code += '\n\nexport type Session = typeof session.$inferSelect;';
- }
- if (!code.includes('export type User =')) {
- code += '\n\nexport type User = typeof user.$inferSelect;';
+ if (typescript) {
+ if (!code.includes('export type Session =')) {
+ code += '\n\nexport type Session = typeof session.$inferSelect;';
+ }
+ if (!code.includes('export type User =')) {
+ code += '\n\nexport type User = typeof user.$inferSelect;';
+ }
}
return code;
}
From 7588d412678a5f651c67bc46c1acc4452c3b89e1 Mon Sep 17 00:00:00 2001
From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com>
Date: Sun, 13 Oct 2024 13:18:39 -0400
Subject: [PATCH 14/18] fix jsdoc comments
---
packages/adders/lucia/index.ts | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/packages/adders/lucia/index.ts b/packages/adders/lucia/index.ts
index 3f22f6cb3..eba45f567 100644
--- a/packages/adders/lucia/index.ts
+++ b/packages/adders/lucia/index.ts
@@ -218,17 +218,23 @@ export default defineAdder({
export const sessionCookieName = 'auth-session';
+ ${ts('', '/** @returns {string} */')}
function generateSessionToken()${ts(': string')} {
const bytes = crypto.getRandomValues(new Uint8Array(20));
const token = encodeBase32LowerCaseNoPadding(bytes);
return token;
}
+ ${ts('', '/**')}
+ ${ts('', ' * @param {number} length')}
+ ${ts('', ' * @returns {string}')}
+ ${ts('', ' */')}
export function generateId(length${ts(': number')})${ts(': string')} {
const alphabet = 'abcdefghijklmnopqrstuvwxyz0123456789';
return generateRandomString({ read: (bytes) => crypto.getRandomValues(bytes) }, alphabet, length);
}
+ ${ts('', '/** @param {string} userId */')}
export async function createSession(userId${ts(': string')})${ts(': Promise')} {
const token = generateSessionToken();
const sessionId = encodeHexLowerCase(sha256(new TextEncoder().encode(token)));
@@ -242,6 +248,7 @@ export default defineAdder({
}
${ts('export type SessionValidationResult = Awaited>;\n')}
+ ${ts('', '/** @param {string} sessionId */')}
export async function validateSession(sessionId${ts(': string')}) {
const [result] = await db
.select({
@@ -275,7 +282,11 @@ export default defineAdder({
return { session, user };
}
-
+
+ ${ts('', '/**')}
+ ${ts('', ' * @param {string} sessionId')}
+ ${ts('', ' * @returns {Promise}')}
+ ${ts('', ' */')}
export async function invalidateSession(sessionId${ts(': string')})${ts(': Promise')} {
await db.delete(table.session).where(eq(table.session.id, sessionId));
}
From 5664544212d600eaff5fddb94e6af93f84053225 Mon Sep 17 00:00:00 2001
From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com>
Date: Sun, 13 Oct 2024 13:45:20 -0400
Subject: [PATCH 15/18] add individual functions for better compatibility
---
packages/adders/lucia/index.ts | 203 +++++++++++++++++++--------------
1 file changed, 115 insertions(+), 88 deletions(-)
diff --git a/packages/adders/lucia/index.ts b/packages/adders/lucia/index.ts
index 5da09a93e..20e404b5f 100644
--- a/packages/adders/lucia/index.ts
+++ b/packages/adders/lucia/index.ts
@@ -1,3 +1,4 @@
+import MagicString from 'magic-string';
import {
colors,
dedent,
@@ -206,98 +207,124 @@ export default defineAdder({
},
{
name: ({ kit, typescript }) => `${kit?.libDirectory}/server/auth.${typescript ? 'ts' : 'js'}`,
- content: ({ content, typescript, kit }) => {
- if (content) {
- const filePath = `${kit!.libDirectory}/server/auth.${typescript ? 'ts' : 'js'}`;
- log.warn(`Existing ${colors.yellow(filePath)} file. Could not update.`);
- return content;
- }
- const [ts] = utils.createPrinter(typescript);
- return dedent`
- import { eq } from 'drizzle-orm';
- import { sha256 } from '@oslojs/crypto/sha2';
- import { generateRandomString } from '@oslojs/crypto/random';
- import { encodeBase32LowerCaseNoPadding, encodeHexLowerCase } from '@oslojs/encoding';
- import { db } from '$lib/server/db';
- import * as table from '$lib/server/db/schema';
-
- const DAY_IN_MS = 1000 * 60 * 60 * 24;
-
- export const sessionCookieName = 'auth-session';
-
- ${ts('', '/** @returns {string} */')}
- function generateSessionToken()${ts(': string')} {
- const bytes = crypto.getRandomValues(new Uint8Array(20));
- const token = encodeBase32LowerCaseNoPadding(bytes);
- return token;
- }
-
- ${ts('', '/**')}
- ${ts('', ' * @param {number} length')}
- ${ts('', ' * @returns {string}')}
- ${ts('', ' */')}
- export function generateId(length${ts(': number')})${ts(': string')} {
- const alphabet = 'abcdefghijklmnopqrstuvwxyz0123456789';
- return generateRandomString({ read: (bytes) => crypto.getRandomValues(bytes) }, alphabet, length);
- }
-
- ${ts('', '/** @param {string} userId */')}
- export async function createSession(userId${ts(': string')})${ts(': Promise')} {
- const token = generateSessionToken();
- const sessionId = encodeHexLowerCase(sha256(new TextEncoder().encode(token)));
- const session${ts(': table.Session')} = {
- id: sessionId,
- userId,
- expiresAt: new Date(Date.now() + DAY_IN_MS * 30)
- };
- await db.insert(table.session).values(session);
- return session;
- }
+ content: ({ content, typescript }) => {
+ const { ast, generateCode } = parseScript(content);
- ${ts('export type SessionValidationResult = Awaited>;\n')}
- ${ts('', '/** @param {string} sessionId */')}
- export async function validateSession(sessionId${ts(': string')}) {
- const [result] = await db
- .select({
- // Adjust user table here to tweak returned data
- user: { id: table.user.id, username: table.user.username },
- session: table.session
- })
- .from(table.session)
- .innerJoin(table.user, eq(table.session.userId, table.user.id))
- .where(eq(table.session.id, sessionId));
-
- if (!result) {
- return { session: null, user: null };
- }
- const { session, user } = result;
+ imports.addNamespace(ast, '$lib/server/db/schema', 'table');
+ imports.addNamed(ast, '$lib/server/db', { db: 'db' });
+ imports.addNamed(ast, '@oslojs/encoding', {
+ encodeBase32LowerCaseNoPadding: 'encodeBase32LowerCaseNoPadding',
+ encodeHexLowerCase: 'encodeHexLowerCase'
+ });
+ imports.addNamed(ast, '@oslojs/crypto/random', {
+ generateRandomString: 'generateRandomString'
+ });
+ imports.addNamed(ast, '@oslojs/crypto/sha2', { sha256: 'sha256' });
+ imports.addNamed(ast, 'drizzle-orm', { eq: 'eq' });
- const sessionExpired = Date.now() >= session.expiresAt.getTime();
- if (sessionExpired) {
- await db.delete(table.session).where(eq(table.session.id, session.id));
- return { session: null, user: null };
- }
+ const ms = new MagicString(generateCode().trim());
+ const [ts] = utils.createPrinter(typescript);
- const renewSession = Date.now() >= session.expiresAt.getTime() - DAY_IN_MS * 15;
- if (renewSession) {
- session.expiresAt = new Date(Date.now() + DAY_IN_MS * 30);
- await db
- .update(table.session)
- .set({ expiresAt: session.expiresAt })
- .where(eq(table.session.id, session.id));
- }
+ if (!ms.original.includes('const DAY_IN_MS')) {
+ ms.append('\n\nconst DAY_IN_MS = 1000 * 60 * 60 * 24;');
+ }
+ if (!ms.original.includes('export const sessionCookieName')) {
+ ms.append("\n\nexport const sessionCookieName = 'auth-session';");
+ }
+ if (!ms.original.includes('function generateSessionToken')) {
+ const generateSessionToken = dedent`
+ ${ts('', '/** @returns {string} */')}
+ function generateSessionToken()${ts(': string')} {
+ const bytes = crypto.getRandomValues(new Uint8Array(20));
+ const token = encodeBase32LowerCaseNoPadding(bytes);
+ return token;
+ }`;
+ ms.append(`\n\n${generateSessionToken}`);
+ }
+ if (!ms.original.includes('function generateId')) {
+ const generateId = dedent`
+ ${ts('', '/**')}
+ ${ts('', ' * @param {number} length')}
+ ${ts('', ' * @returns {string}')}
+ ${ts('', ' */')}
+ export function generateId(length${ts(': number')})${ts(': string')} {
+ const alphabet = 'abcdefghijklmnopqrstuvwxyz0123456789';
+ return generateRandomString({ read: (bytes) => crypto.getRandomValues(bytes) }, alphabet, length);
+ }`;
+ ms.append(`\n\n${generateId}`);
+ }
+ if (!ms.original.includes('async function createSession')) {
+ const createSession = dedent`
+ ${ts('', '/** @param {string} userId */')}
+ export async function createSession(userId${ts(': string')})${ts(': Promise')} {
+ const token = generateSessionToken();
+ const sessionId = encodeHexLowerCase(sha256(new TextEncoder().encode(token)));
+ const session${ts(': table.Session')} = {
+ id: sessionId,
+ userId,
+ expiresAt: new Date(Date.now() + DAY_IN_MS * 30)
+ };
+ await db.insert(table.session).values(session);
+ return session;
+ }`;
+ ms.append(`\n\n${createSession}`);
+ }
+ if (!ms.original.includes('async function invalidateSession')) {
+ const invalidateSession = dedent`
+ ${ts('', '/**')}
+ ${ts('', ' * @param {string} sessionId')}
+ ${ts('', ' * @returns {Promise}')}
+ ${ts('', ' */')}
+ export async function invalidateSession(sessionId${ts(': string')})${ts(': Promise')} {
+ await db.delete(table.session).where(eq(table.session.id, sessionId));
+ }`;
+ ms.append(`\n\n${invalidateSession}`);
+ }
+ if (typescript && !ms.original.includes('export type SessionValidationResult')) {
+ const sessionType =
+ 'export type SessionValidationResult = Awaited>;';
+ ms.append(`\n\n${sessionType}`);
+ }
+ if (!ms.original.includes('async function validateSession')) {
+ const validateSession = dedent`
+ ${ts('', '/** @param {string} sessionId */')}
+ export async function validateSession(sessionId${ts(': string')}) {
+ const [result] = await db
+ .select({
+ // Adjust user table here to tweak returned data
+ user: { id: table.user.id, username: table.user.username },
+ session: table.session
+ })
+ .from(table.session)
+ .innerJoin(table.user, eq(table.session.userId, table.user.id))
+ .where(eq(table.session.id, sessionId));
+
+ if (!result) {
+ return { session: null, user: null };
+ }
+ const { session, user } = result;
+
+ const sessionExpired = Date.now() >= session.expiresAt.getTime();
+ if (sessionExpired) {
+ await db.delete(table.session).where(eq(table.session.id, session.id));
+ return { session: null, user: null };
+ }
+
+ const renewSession = Date.now() >= session.expiresAt.getTime() - DAY_IN_MS * 15;
+ if (renewSession) {
+ session.expiresAt = new Date(Date.now() + DAY_IN_MS * 30);
+ await db
+ .update(table.session)
+ .set({ expiresAt: session.expiresAt })
+ .where(eq(table.session.id, session.id));
+ }
+
+ return { session, user };
+ }`;
+ ms.append(`\n\n${validateSession}`);
+ }
- return { session, user };
- }
-
- ${ts('', '/**')}
- ${ts('', ' * @param {string} sessionId')}
- ${ts('', ' * @returns {Promise}')}
- ${ts('', ' */')}
- export async function invalidateSession(sessionId${ts(': string')})${ts(': Promise')} {
- await db.delete(table.session).where(eq(table.session.id, sessionId));
- }
- `;
+ return ms.toString();
}
},
{
From 6d53cdacfc550e33d636f868bdc7244f83dfea17 Mon Sep 17 00:00:00 2001
From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com>
Date: Sun, 13 Oct 2024 14:12:54 -0400
Subject: [PATCH 16/18] update docs
---
packages/adders/lucia/index.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/packages/adders/lucia/index.ts b/packages/adders/lucia/index.ts
index 20e404b5f..fd688150c 100644
--- a/packages/adders/lucia/index.ts
+++ b/packages/adders/lucia/index.ts
@@ -37,7 +37,7 @@ export default defineAdder({
name: 'Lucia',
description: 'An auth library that abstracts away the complexity of handling sessions',
environments: { svelte: false, kit: true },
- documentation: 'https://lucia-auth.com',
+ documentation: 'https://lucia-next.pages.dev',
options,
packages: [
{ name: '@oslojs/crypto', version: '^1.0.1', dev: false },
From 42e24a74119ee6ea4b303ec7471a3ad0b248d41d Mon Sep 17 00:00:00 2001
From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com>
Date: Mon, 14 Oct 2024 12:45:32 -0400
Subject: [PATCH 17/18] fix spacing
---
packages/adders/lucia/index.ts | 12 ++++--------
1 file changed, 4 insertions(+), 8 deletions(-)
diff --git a/packages/adders/lucia/index.ts b/packages/adders/lucia/index.ts
index fd688150c..758b3aace 100644
--- a/packages/adders/lucia/index.ts
+++ b/packages/adders/lucia/index.ts
@@ -382,8 +382,7 @@ export default defineAdder({
import { db } from '$lib/server/db';
import * as auth from '$lib/server/auth';
import * as table from '$lib/server/db/schema';
- ${ts(`import type { Actions, PageServerLoad } from './$types';`)}
-
+ ${ts(`import type { Actions, PageServerLoad } from './$types';\n`)}
export const load${ts(': PageServerLoad')} = async (event) => {
if (event.locals.user) {
return redirect(302, '/demo');
@@ -507,8 +506,7 @@ export default defineAdder({
return dedent`
@@ -545,8 +543,7 @@ export default defineAdder({
return dedent`
import * as auth from '$lib/server/auth';
import { fail, redirect } from '@sveltejs/kit';
- ${ts(`import type { Actions, PageServerLoad } from './$types';`)}
-
+ ${ts(`import type { Actions, PageServerLoad } from './$types';\n`)}
export const load${ts(': PageServerLoad')} = async (event) => {
if (!event.locals.user) {
return redirect(302, '/demo/login');
@@ -582,8 +579,7 @@ export default defineAdder({
return dedent`
From 72d37c1872bc60a790d738f58a0561448ceb9ae1 Mon Sep 17 00:00:00 2001
From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com>
Date: Mon, 14 Oct 2024 12:50:46 -0400
Subject: [PATCH 18/18] update tests
---
packages/core/tests/js/imports/namespaced-import/output.ts | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/packages/core/tests/js/imports/namespaced-import/output.ts b/packages/core/tests/js/imports/namespaced-import/output.ts
index ca6f2f5b3..56eda1b3d 100644
--- a/packages/core/tests/js/imports/namespaced-import/output.ts
+++ b/packages/core/tests/js/imports/namespaced-import/output.ts
@@ -1,2 +1,2 @@
-import * as bar from "./some-file";
-import * as foo from "package";
\ No newline at end of file
+import * as bar from './some-file';
+import * as foo from 'package';
\ No newline at end of file