@rttnd/gau 0.3.6 → 0.3.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-X6HBHPJD.js → chunk-TLWTWCXQ.js} +1 -1
- package/dist/chunk-TLWTWCXQ.js.map +1 -0
- package/dist/{chunk-UTAPXIXP.js → chunk-UVM2UHAF.js} +1 -1
- package/dist/chunk-UVM2UHAF.js.map +1 -0
- package/dist/chunk-WEGQGDWC.js +1 -0
- package/dist/chunk-WEGQGDWC.js.map +1 -0
- package/dist/src/adapters/drizzle/index.js +1 -1
- package/dist/src/adapters/drizzle/sqlite.d.ts +1 -0
- package/dist/src/adapters/drizzle/sqlite.d.ts.map +1 -1
- package/dist/src/adapters/index.js +1 -1
- package/dist/src/adapters/memory/index.d.ts.map +1 -1
- package/dist/src/adapters/memory/index.js +1 -1
- package/dist/src/client/solid/index.d.ts.map +1 -1
- package/dist/src/client/solid/index.jsx +11 -5
- package/dist/src/client/svelte/index.svelte.js.map +1 -1
- package/dist/src/core/createAuth.d.ts +26 -1
- package/dist/src/core/createAuth.d.ts.map +1 -1
- package/dist/src/core/handlers/callback.d.ts.map +1 -1
- package/dist/src/core/handlers/index.js +1 -1
- package/dist/src/core/index.d.ts +1 -0
- package/dist/src/core/index.d.ts.map +1 -1
- package/dist/src/core/index.js +1 -1
- package/dist/src/index.js +1 -1
- package/dist/src/jwt/index.js +1 -1
- package/dist/src/solidstart/index.js +1 -1
- package/dist/src/sveltekit/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-BU67DYGK.js +0 -1
- package/dist/chunk-BU67DYGK.js.map +0 -1
- package/dist/chunk-UTAPXIXP.js.map +0 -1
- package/dist/chunk-X6HBHPJD.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
import{is as e}from"drizzle-orm";import{MySqlDatabase as r}from"drizzle-orm/mysql-core";import{PgDatabase as t}from"drizzle-orm/pg-core";import{BaseSQLiteDatabase as n}from"drizzle-orm/sqlite-core";import{and as a,eq as i}from"drizzle-orm";import{sql as o}from"drizzle-orm";async function s(e,r){if("async"===e.session?.mode||"async"===e.mode)return e.transaction(r);e.run(o`BEGIN`);try{const t=await r(e);return e.run(o`COMMIT`),t}catch(r){throw e.run(o`ROLLBACK`),r}}function c(o,c,
|
|
1
|
+
import{is as e}from"drizzle-orm";import{MySqlDatabase as r}from"drizzle-orm/mysql-core";import{PgDatabase as t}from"drizzle-orm/pg-core";import{BaseSQLiteDatabase as n}from"drizzle-orm/sqlite-core";import{and as a,eq as i}from"drizzle-orm";import{sql as o}from"drizzle-orm";async function s(e,r){if("async"===e.session?.mode||"async"===e.mode)return e.transaction(r);e.run(o`BEGIN`);try{const t=await r(e);return e.run(o`COMMIT`),t}catch(r){throw e.run(o`ROLLBACK`),r}}function c(o,c,l){if(e(o,n))return function(e,r,t){const n=e=>e?{...e}:null;return{async getUser(t){const a=await e.select().from(r).where(i(r.id,t)).get();return n(a)},async getUserByEmail(t){const a=await e.select().from(r).where(i(r.email,t)).get();return n(a)},async getUserByAccount(o,s){const c=await e.select().from(r).innerJoin(t,i(r.id,t.userId)).where(a(i(t.provider,o),i(t.providerAccountId,s))).get();return n(c?.users)},getAccounts:async r=>await e.select().from(t).where(i(t.userId,r)).all(),async getUserAndAccounts(a){const o=await e.select().from(r).where(i(r.id,a)).leftJoin(t,i(r.id,t.userId)).all();return o.length?{user:n(o[0].users),accounts:o.map(e=>e.accounts).filter(Boolean)}:null},async createUser(t){const a=t.id??crypto.randomUUID();return await s(e,async e=>{await e.insert(r).values({id:a,name:t.name??null,email:t.email??null,image:t.image??null,emailVerified:t.emailVerified??null,...r.role?{role:t.role??null}:{},createdAt:new Date,updatedAt:new Date}).run();const o=await e.select().from(r).where(i(r.id,a)).get();return n(o)})},async linkAccount(r){await e.insert(t).values({type:"oauth",...r}).run()},async unlinkAccount(r,n){await e.delete(t).where(a(i(t.provider,r),i(t.providerAccountId,n))).run()},updateUser:async t=>await s(e,async e=>{await e.update(r).set({name:t.name,email:t.email,image:t.image,emailVerified:t.emailVerified,...r.role?{role:t.role}:{},updatedAt:new Date}).where(i(r.id,t.id)).run();const a=await e.select().from(r).where(i(r.id,t.id)).get();return n(a)}),async deleteUser(t){await e.delete(r).where(i(r.id,t)).run()}}}(o,c,l);if(e(o,r))return function(){throw new Error("MySQL adapter is not yet implemented.")}();if(e(o,t))return function(){throw new Error("PostgreSQL adapter is not yet implemented.")}();throw new Error(`Unsupported database type (${typeof o}) in gau Drizzle adapter.`)}export{c as DrizzleAdapter};//# sourceMappingURL=chunk-TLWTWCXQ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/adapters/drizzle/index.ts","../src/adapters/drizzle/mysql.ts","../src/adapters/drizzle/pg.ts","../src/adapters/drizzle/sqlite.ts","../src/adapters/drizzle/transaction.ts"],"sourcesContent":["import type { Adapter } from '../../core/index'\nimport type { AccountsTable, UsersTable } from './sqlite'\nimport { is } from 'drizzle-orm'\nimport { MySqlDatabase } from 'drizzle-orm/mysql-core'\nimport { PgDatabase } from 'drizzle-orm/pg-core'\n\nimport { BaseSQLiteDatabase } from 'drizzle-orm/sqlite-core'\nimport { MySqlDrizzleAdapter } from './mysql'\nimport { PostgresDrizzleAdapter } from './pg'\nimport { SQLiteDrizzleAdapter } from './sqlite'\n\nexport function DrizzleAdapter<\n U extends UsersTable,\n A extends AccountsTable,\n>(\n db:\n | BaseSQLiteDatabase<'sync' | 'async', any, any>\n | MySqlDatabase<any, any, any, any>\n | PgDatabase<any, any, any>,\n users: U,\n accounts: A,\n): Adapter {\n if (is(db, BaseSQLiteDatabase))\n return SQLiteDrizzleAdapter(db, users, accounts)\n\n if (is(db, MySqlDatabase))\n // @ts-expect-error Not implemented\n return MySqlDrizzleAdapter(db, users, accounts)\n\n if (is(db, PgDatabase))\n // @ts-expect-error Not implemented\n return PostgresDrizzleAdapter(db, users, accounts)\n\n throw new Error(\n `Unsupported database type (${typeof db}) in gau Drizzle adapter.`,\n )\n}\n","// TODO: Implement MySQL adapter for gau\nexport function MySqlDrizzleAdapter(): never {\n throw new Error('MySQL adapter is not yet implemented.')\n}\n","// TODO: Implement PostgreSQL adapter for gau\nexport function PostgresDrizzleAdapter(): never {\n throw new Error('PostgreSQL adapter is not yet implemented.')\n}\n","import type { AnyColumn, InferInsertModel, InferSelectModel, Table } from 'drizzle-orm'\nimport type { BaseSQLiteDatabase } from 'drizzle-orm/sqlite-core'\nimport type { Account, Adapter, NewAccount, NewUser, User } from '../../core/index'\nimport { and, eq } from 'drizzle-orm'\nimport { transaction } from './transaction'\n\nexport type UsersTable = Table & {\n id: AnyColumn\n name: AnyColumn\n email: AnyColumn\n image: AnyColumn\n emailVerified: AnyColumn\n role?: AnyColumn\n createdAt: AnyColumn\n updatedAt: AnyColumn\n}\n\nexport type AccountsTable = Table & {\n userId: AnyColumn\n provider: AnyColumn\n providerAccountId: AnyColumn\n}\n\n/**\n * SQLite-specific Drizzle adapter.\n *\n * Pass concrete `users` and `accounts` `Table` objects\n * with the columns we access (`id`, `email`, `userId`, `provider`, `providerAccountId`).\n */\nexport function SQLiteDrizzleAdapter<\n DB extends BaseSQLiteDatabase<'sync' | 'async', any, any>,\n U extends UsersTable,\n A extends AccountsTable,\n>(db: DB, Users: U, Accounts: A): Adapter {\n type DBUser = InferSelectModel<U>\n type DBAccount = InferSelectModel<A>\n type DBInsertUser = InferInsertModel<U>\n type DBInsertAccount = InferInsertModel<A>\n\n const toUser = (row: DBUser | undefined | null): User | null =>\n row ? ({ ...(row as any) }) : null\n\n return {\n async getUser(id) {\n const user: DBUser | undefined = await db\n .select()\n .from(Users)\n .where(eq(Users.id, id))\n .get()\n return toUser(user)\n },\n\n async getUserByEmail(email) {\n const user: DBUser | undefined = await db\n .select()\n .from(Users)\n .where(eq(Users.email, email))\n .get()\n return toUser(user)\n },\n\n async getUserByAccount(provider, providerAccountId) {\n const result: DBUser | undefined = await db\n .select()\n .from(Users)\n .innerJoin(Accounts, eq(Users.id, Accounts.userId))\n .where(and(eq(Accounts.provider, provider), eq(Accounts.providerAccountId, providerAccountId)))\n .get()\n return toUser(result?.users)\n },\n\n async getAccounts(userId) {\n const accounts: DBAccount[] = await db\n .select()\n .from(Accounts)\n .where(eq(Accounts.userId, userId))\n .all()\n return accounts as Account[]\n },\n\n async getUserAndAccounts(userId) {\n const result = await db\n .select()\n .from(Users)\n .where(eq(Users.id, userId))\n .leftJoin(Accounts, eq(Users.id, Accounts.userId))\n .all()\n\n if (!result.length)\n return null\n\n const user = toUser(result[0]!.users)!\n const accounts = result\n .map(row => row.accounts)\n .filter(Boolean) as Account[]\n\n return { user, accounts }\n },\n\n async createUser(data: NewUser) {\n const id = data.id ?? crypto.randomUUID()\n return await transaction(db, async (tx) => {\n await tx\n .insert(Users)\n .values({\n id,\n name: data.name ?? null,\n email: data.email ?? null,\n image: data.image ?? null,\n emailVerified: data.emailVerified ?? null,\n ...(Users.role ? { role: data.role ?? null } : {}),\n createdAt: new Date(),\n updatedAt: new Date(),\n } as DBInsertUser)\n .run()\n\n const result: DBUser | undefined = await tx.select().from(Users).where(eq(Users.id, id)).get()\n return toUser(result) as User\n })\n },\n\n async linkAccount(data: NewAccount) {\n await db\n .insert(Accounts)\n .values({\n type: 'oauth',\n ...data,\n } as DBInsertAccount)\n .run()\n },\n\n async unlinkAccount(provider, providerAccountId) {\n await db\n .delete(Accounts)\n .where(and(eq(Accounts.provider, provider), eq(Accounts.providerAccountId, providerAccountId)))\n .run()\n },\n\n async updateUser(partial) {\n return await transaction(db, async (tx) => {\n await tx\n .update(Users)\n .set({\n name: partial.name,\n email: partial.email,\n image: partial.image,\n emailVerified: partial.emailVerified,\n ...(Users.role ? { role: partial.role } : {}),\n updatedAt: new Date(),\n } as Partial<DBInsertUser>)\n .where(eq(Users.id, partial.id))\n .run()\n\n const result: DBUser | undefined = await tx.select().from(Users).where(eq(Users.id, partial.id)).get()\n return toUser(result) as User\n })\n },\n\n async deleteUser(id) {\n await db.delete(Users).where(eq(Users.id, id)).run()\n },\n }\n}\n","import type { BaseSQLiteDatabase } from 'drizzle-orm/sqlite-core'\nimport { sql } from 'drizzle-orm'\n\n/**\n * A helper to run transactions across both sync (`better-sqlite3`)\n * and async (`libsql`) Drizzle drivers.\n *\n * It checks for the `mode` property on the Drizzle DB instance, which is\n * `'sync'` or `'async'`.\n *\n * @param db The Drizzle database instance.\n * @param callback The function to execute within the transaction.\n */\nexport async function transaction<T>(\n db: BaseSQLiteDatabase<'sync' | 'async', any, any>,\n callback: (\n tx: Omit<typeof db, 'transaction'>,\n ) => Promise<T>,\n): Promise<T> {\n const isAsync = (db as any).session?.mode === 'async' || (db as any).mode === 'async'\n\n if (isAsync)\n return db.transaction(callback)\n\n db.run(sql`BEGIN`)\n try {\n const result = await callback(db)\n db.run(sql`COMMIT`)\n return result\n }\n catch (e) {\n db.run(sql`ROLLBACK`)\n throw e\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
function e(e){return`${e.provider}:${e.providerAccountId}`}function n(){const n=new Map,t=new Map,r=new Map;return{getUser:async e=>n.get(e)??null,async getUserByEmail(e){const r=t.get(e);return r?n.get(r)??null:null},async getUserByAccount(t,s){const c=r.get(e({provider:t,providerAccountId:s}));return c?n.get(c)??null:null},async getAccounts(e){const n=[];for(const[t,s]of r.entries())if(s===e){const[r,s]=t.split(":");n.push({userId:e,provider:r,providerAccountId:s})}return n},async getUserAndAccounts(e){const n=await this.getUser(e);if(!n)return null;return{user:n,accounts:await this.getAccounts(e)}},async createUser(e){const r=e.id??crypto.randomUUID(),s={id:r,name:e.name??null,email:e.email??null,image:e.image??null,emailVerified:null};return n.set(r,s),s.email&&t.set(s.email,r),s},async linkAccount(n){r.set(e(n),n.userId)},async unlinkAccount(n,t){r.delete(e({provider:n,providerAccountId:t}))},async updateUser(e){const r=n.get(e.id);if(!r)throw new Error("User not found");const s={...r,...e};return n.set(s.id,s),s.email&&t.set(s.email,s.id),s},async deleteUser(e){const s=n.get(e);s?.email&&t.delete(s.email),n.delete(e);for(const[n,t]of r.entries())t===e&&r.delete(n)}}}export{n as MemoryAdapter};//# sourceMappingURL=chunk-
|
|
1
|
+
function e(e){return`${e.provider}:${e.providerAccountId}`}function n(){const n=new Map,t=new Map,r=new Map;return{getUser:async e=>n.get(e)??null,async getUserByEmail(e){const r=t.get(e);return r?n.get(r)??null:null},async getUserByAccount(t,s){const c=r.get(e({provider:t,providerAccountId:s}));return c?n.get(c)??null:null},async getAccounts(e){const n=[];for(const[t,s]of r.entries())if(s===e){const[r,s]=t.split(":");n.push({userId:e,provider:r,providerAccountId:s})}return n},async getUserAndAccounts(e){const n=await this.getUser(e);if(!n)return null;return{user:n,accounts:await this.getAccounts(e)}},async createUser(e){const r=e.id??crypto.randomUUID(),s={id:r,name:e.name??null,email:e.email??null,image:e.image??null,emailVerified:e.emailVerified??null,role:e.role??void 0};return n.set(r,s),s.email&&t.set(s.email,r),s},async linkAccount(n){r.set(e(n),n.userId)},async unlinkAccount(n,t){r.delete(e({provider:n,providerAccountId:t}))},async updateUser(e){const r=n.get(e.id);if(!r)throw new Error("User not found");const s={...r,...e};return n.set(s.id,s),s.email&&t.set(s.email,s.id),s},async deleteUser(e){const s=n.get(e);s?.email&&t.delete(s.email),n.delete(e);for(const[n,t]of r.entries())t===e&&r.delete(n)}}}export{n as MemoryAdapter};//# sourceMappingURL=chunk-UVM2UHAF.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/adapters/memory/index.ts"],"sourcesContent":["import type { Account, Adapter, NewAccount, NewUser, User } from '../../core/index'\n\ninterface InternalAccountKey {\n provider: string\n providerAccountId: string\n}\n\nfunction accountKey(k: InternalAccountKey): string {\n return `${k.provider}:${k.providerAccountId}`\n}\n\nexport function MemoryAdapter(): Adapter {\n const users = new Map<string, User>()\n const usersByEmail = new Map<string, string>() // email -> userId\n const accounts = new Map<string, string>() // accountKey -> userId\n\n return {\n async getUser(id) {\n return users.get(id) ?? null\n },\n\n async getUserByEmail(email) {\n const id = usersByEmail.get(email)\n if (!id)\n return null\n return users.get(id) ?? null\n },\n\n async getUserByAccount(provider, providerAccountId) {\n const id = accounts.get(accountKey({ provider, providerAccountId }))\n if (!id)\n return null\n return users.get(id) ?? null\n },\n\n async getAccounts(userId) {\n const userAccounts: Account[] = []\n for (const [key, accUserId] of accounts.entries()) {\n if (accUserId === userId) {\n const [provider, providerAccountId] = key.split(':') as [string, string]\n userAccounts.push({ userId, provider, providerAccountId })\n }\n }\n return userAccounts\n },\n\n async getUserAndAccounts(userId) {\n const user = await this.getUser(userId)\n if (!user)\n return null\n const accounts = await this.getAccounts(userId)\n return { user, accounts }\n },\n\n async createUser(data: NewUser) {\n const id = data.id ?? crypto.randomUUID()\n const user: User = {\n id,\n name: data.name ?? null,\n email: data.email ?? null,\n image: data.image ?? null,\n emailVerified: data.emailVerified ?? null,\n role: data.role ?? undefined,\n }\n users.set(id, user)\n if (user.email)\n usersByEmail.set(user.email, id)\n return user\n },\n\n async linkAccount(data: NewAccount) {\n accounts.set(accountKey(data), data.userId)\n },\n\n async unlinkAccount(provider, providerAccountId) {\n accounts.delete(accountKey({ provider, providerAccountId }))\n },\n\n async updateUser(partial) {\n const existing = users.get(partial.id)\n if (!existing)\n throw new Error('User not found')\n const updated: User = { ...existing, ...partial }\n users.set(updated.id, updated)\n if (updated.email)\n usersByEmail.set(updated.email, updated.id)\n return updated\n },\n async deleteUser(id) {\n const user = users.get(id)\n if (user?.email)\n usersByEmail.delete(user.email)\n users.delete(id)\n for (const [key, userId] of accounts.entries()) {\n if (userId === id)\n accounts.delete(key)\n }\n },\n }\n}\n"],"mappings":";AAOA,SAAS,WAAW,GAA+B;AACjD,SAAO,GAAG,EAAE,QAAQ,IAAI,EAAE,iBAAiB;AAC7C;AAEO,SAAS,gBAAyB;AACvC,QAAM,QAAQ,oBAAI,IAAkB;AACpC,QAAM,eAAe,oBAAI,IAAoB;AAC7C,QAAM,WAAW,oBAAI,IAAoB;AAEzC,SAAO;AAAA,IACL,MAAM,QAAQ,IAAI;AAChB,aAAO,MAAM,IAAI,EAAE,KAAK;AAAA,IAC1B;AAAA,IAEA,MAAM,eAAe,OAAO;AAC1B,YAAM,KAAK,aAAa,IAAI,KAAK;AACjC,UAAI,CAAC;AACH,eAAO;AACT,aAAO,MAAM,IAAI,EAAE,KAAK;AAAA,IAC1B;AAAA,IAEA,MAAM,iBAAiB,UAAU,mBAAmB;AAClD,YAAM,KAAK,SAAS,IAAI,WAAW,EAAE,UAAU,kBAAkB,CAAC,CAAC;AACnE,UAAI,CAAC;AACH,eAAO;AACT,aAAO,MAAM,IAAI,EAAE,KAAK;AAAA,IAC1B;AAAA,IAEA,MAAM,YAAY,QAAQ;AACxB,YAAM,eAA0B,CAAC;AACjC,iBAAW,CAAC,KAAK,SAAS,KAAK,SAAS,QAAQ,GAAG;AACjD,YAAI,cAAc,QAAQ;AACxB,gBAAM,CAAC,UAAU,iBAAiB,IAAI,IAAI,MAAM,GAAG;AACnD,uBAAa,KAAK,EAAE,QAAQ,UAAU,kBAAkB,CAAC;AAAA,QAC3D;AAAA,MACF;AACA,aAAO;AAAA,IACT;AAAA,IAEA,MAAM,mBAAmB,QAAQ;AAC/B,YAAM,OAAO,MAAM,KAAK,QAAQ,MAAM;AACtC,UAAI,CAAC;AACH,eAAO;AACT,YAAMA,YAAW,MAAM,KAAK,YAAY,MAAM;AAC9C,aAAO,EAAE,MAAM,UAAAA,UAAS;AAAA,IAC1B;AAAA,IAEA,MAAM,WAAW,MAAe;AAC9B,YAAM,KAAK,KAAK,MAAM,OAAO,WAAW;AACxC,YAAM,OAAa;AAAA,QACjB;AAAA,QACA,MAAM,KAAK,QAAQ;AAAA,QACnB,OAAO,KAAK,SAAS;AAAA,QACrB,OAAO,KAAK,SAAS;AAAA,QACrB,eAAe,KAAK,iBAAiB;AAAA,QACrC,MAAM,KAAK,QAAQ;AAAA,MACrB;AACA,YAAM,IAAI,IAAI,IAAI;AAClB,UAAI,KAAK;AACP,qBAAa,IAAI,KAAK,OAAO,EAAE;AACjC,aAAO;AAAA,IACT;AAAA,IAEA,MAAM,YAAY,MAAkB;AAClC,eAAS,IAAI,WAAW,IAAI,GAAG,KAAK,MAAM;AAAA,IAC5C;AAAA,IAEA,MAAM,cAAc,UAAU,mBAAmB;AAC/C,eAAS,OAAO,WAAW,EAAE,UAAU,kBAAkB,CAAC,CAAC;AAAA,IAC7D;AAAA,IAEA,MAAM,WAAW,SAAS;AACxB,YAAM,WAAW,MAAM,IAAI,QAAQ,EAAE;AACrC,UAAI,CAAC;AACH,cAAM,IAAI,MAAM,gBAAgB;AAClC,YAAM,UAAgB,EAAE,GAAG,UAAU,GAAG,QAAQ;AAChD,YAAM,IAAI,QAAQ,IAAI,OAAO;AAC7B,UAAI,QAAQ;AACV,qBAAa,IAAI,QAAQ,OAAO,QAAQ,EAAE;AAC5C,aAAO;AAAA,IACT;AAAA,IACA,MAAM,WAAW,IAAI;AACnB,YAAM,OAAO,MAAM,IAAI,EAAE;AACzB,UAAI,MAAM;AACR,qBAAa,OAAO,KAAK,KAAK;AAChC,YAAM,OAAO,EAAE;AACf,iBAAW,CAAC,KAAK,MAAM,KAAK,SAAS,QAAQ,GAAG;AAC9C,YAAI,WAAW;AACb,mBAAS,OAAO,GAAG;AAAA,MACvB;AAAA,IACF;AAAA,EACF;AACF;","names":["accounts"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{createJWTSignatureMessage as e,encodeJWT as t,JWSRegisteredHeaders as r,JWTRegisteredClaims as n,parseJWT as s}from"@oslojs/jwt";import{parse as o,serialize as i}from"cookie";var a={path:"/",sameSite:"lax",secure:!0,httpOnly:!0};function c(e){const t=new Map;if(e){const r=o(e);for(const e in r)t.set(e,r[e])}return t}var l=class{constructor(e,t){this.requestCookies=e,this.defaultOptions=t}#e=[];get(e){return this.requestCookies.get(e)}set(e,t,r){const n={...this.defaultOptions,...r};this.#e.push([e,t,n])}delete(e,t){this.set(e,"",{...t,expires:new Date(0),maxAge:0})}toHeaders(){const e=new Headers;for(const[t,r,n]of this.#e)e.append("Set-Cookie",i(t,r,n));return e}},u="__gau-csrf-token",d="__gau-session-token",h="__gau-session-strategy",f="__gau-linking-token",g="__gau-pkce-code-verifier",p="__gau-callback-uri",w=600;function m({adapter:e,providers:t,basePath:r="/api/auth",jwt:n={},session:s={},cookies:o={},trustHosts:i=[],autoLink:c="verifiedEmail",roles:l={}}){const{algorithm:u="ES256",secret:d,iss:h,aud:f,ttl:g=86400}=n,p={...a,...o},w=s.strategy??"auto";if("ES256"===u&&void 0!==d&&"string"!=typeof d)throw new x("For ES256, the secret option must be a string.");const m=new Map(t.map(e=>[e.id,e]));async function y(e,t={}){return N(e,function(e={}){const t={ttl:e.ttl,iss:e.iss??h,aud:e.aud??f,sub:e.sub};if("HS256"===u)return{algorithm:u,secret:e.secret??d,...t};{if(void 0!==e.secret&&"string"!=typeof e.secret)throw new x("For ES256, the secret option must be a string.");const r=e.secret??d;return{algorithm:u,privateKey:e.privateKey,secret:r,...t}}}(t))}async function v(e,t={}){const r=function(e={}){const t={iss:e.iss??h,aud:e.aud??f};if("HS256"===u)return{algorithm:u,secret:e.secret??d,...t};{if(void 0!==e.secret&&"string"!=typeof e.secret)throw new x("For ES256, the secret option must be a string.");const r=e.secret??d;return{algorithm:u,publicKey:e.publicKey,secret:r,...t}}}(t);try{return await F(e,r)}catch{return null}}return{...e,providerMap:m,basePath:r,cookieOptions:p,jwt:{ttl:g},signJWT:y,verifyJWT:v,createSession:async function(e,t={},r=g){return y({sub:e,...t},{ttl:r})},validateSession:async function(t){const r=await v(t);if(!r)return null;const n=await e.getUserAndAccounts(r.sub);if(!n)return null;const{user:s,accounts:o}=n;return{user:s,session:{id:t,...r},accounts:o}},trustHosts:i,autoLink:c,sessionStrategy:w,development:!1,roles:{defaultRole:l.defaultRole??"user",resolveOnCreate:l.resolveOnCreate,adminRoles:l.adminRoles??["admin"],adminUserIds:l.adminUserIds??[]}}}async function y(e,t,r){const n=t.providerMap.get(r);if(!n)return M({error:"Provider not found"},{status:400});const s=new URL(e.url),o=s.searchParams.get("code"),i=s.searchParams.get("state");if(!o||!i)return M({error:"Missing code or state"},{status:400});const a=c(e.headers.get("Cookie")),h=new l(a,t.cookieOptions);let w,m="/";if(i.includes(".")){const[e,t]=i.split(".");w=e;try{m=atob(t??"")||"/"}catch{m="/"}}else w=i;const y=h.get(u);if(!y||y!==w)return M({error:"Invalid CSRF token"},{status:403});const v=h.get(g);if(!v)return M({error:"Missing PKCE code verifier"},{status:400});const S=h.get(p),A=h.get(f);A&&h.delete(f);const k=!!A;if(k){if(!await t.validateSession(A)){h.delete(u),h.delete(g),S&&h.delete(p);const e=I(m);return h.toHeaders().forEach((t,r)=>e.headers.append(r,t)),e}}const{user:b,tokens:C}=await n.validateCallback(o,v,S??void 0);let E=null;const U=await t.getUserByAccount(r,b.id);if(k){if(E=(await t.validateSession(A)).user,!E)return M({error:"User not found"},{status:404});if(U&&U.id!==E.id)return M({error:"Account already linked to another user"},{status:409})}else E=U;if(!E){const n=t.autoLink??"verifiedEmail";if(b.email&&("always"===n||"verifiedEmail"===n&&!0===b.emailVerified)){const e=await t.getUserByEmail(b.email);e&&(E=b.emailVerified&&!e.emailVerified?await t.updateUser({id:e.id,emailVerified:!0}):e)}if(!E)try{let n;try{n=t.roles.resolveOnCreate?.({providerId:r,profile:b,request:e})}catch(e){console.error("roles.resolveOnCreate threw:",e)}E=await t.createUser({name:b.name,email:b.email,image:b.avatar,emailVerified:b.emailVerified,role:n??t.roles.defaultRole})}catch(e){return console.error("Failed to create user:",e),M({error:"Failed to create user"},{status:500})}}if(E&&b.email){const{email:e,emailVerified:r}=E,{email:n,emailVerified:s}=b,o={id:E.id};let i=!1;if(e?e!==n||!0!==s||r||(o.emailVerified=!0,i=!0):(o.email=n,o.emailVerified=s??!1,i=!0),i)try{E=await t.updateUser(o)}catch(e){console.error("Failed to update user after sign-in:",e)}}if(!U){let e,n,s;try{e=C.refreshToken()}catch{e=null}try{const e=C.accessTokenExpiresAt();e&&(n=Math.floor(e.getTime()/1e3))}catch{}try{s=C.idToken()}catch{s=null}try{await t.linkAccount({userId:E.id,provider:r,providerAccountId:b.id,accessToken:C.accessToken(),refreshToken:e,expiresAt:n,tokenType:C.tokenType?.()??null,scope:C.scopes()?.join(" ")??null,idToken:s})}catch(e){return console.error("Error linking account:",e),M({error:"Failed to link account"},{status:500})}}const T=await t.createSession(E.id),H=new URL(e.url),O=new URL(m,e.url),P="token"===t.sessionStrategy,R="cookie"===t.sessionStrategy,x="gau:"===O.protocol,L=H.host!==O.host;if(P||!R&&(x||L)){const e=new URL(O);e.hash=`token=${T}`;const t=`<!DOCTYPE html>\n<html lang="en">\n<head>\n <meta charset="utf-8" />\n <title>Authentication Complete</title>\n <style>\n body {\n font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";\n background-color: #09090b;\n color: #fafafa;\n display: flex;\n justify-content: center;\n align-items: center;\n height: 100vh;\n margin: 0;\n text-align: center;\n }\n .card {\n background-color: #18181b;\n border: 1px solid #27272a;\n border-radius: 0.75rem;\n padding: 2rem;\n max-width: 320px;\n }\n h1 {\n font-size: 1.25rem;\n font-weight: 600;\n margin: 0 0 0.5rem;\n }\n p {\n margin: 0;\n color: #a1a1aa;\n }\n </style>\n <script>\n window.onload = function() {\n const url = ${JSON.stringify(e.toString())};\n window.location.href = url;\n setTimeout(window.close, 500);\n };\n <\/script>\n</head>\n<body>\n <div class="card">\n <h1>Authentication Successful</h1>\n <p>You can now close this window.</p>\n </div>\n</body>\n</html>`;h.delete(u),h.delete(g),S&&h.delete(p);const r=new Response(t,{status:200,headers:{"Content-Type":"text/html; charset=utf-8"}});return h.toHeaders().forEach((e,t)=>{r.headers.append(t,e)}),r}h.set(d,T,{maxAge:t.jwt.ttl,sameSite:t.development?"lax":"none",secure:!t.development}),h.delete(u),h.delete(g),S&&h.delete(p);let N;if("false"===s.searchParams.get("redirect")){const e=await t.getAccounts(E.id);N=M({user:{...E,accounts:e}})}else N=I(m);return h.toHeaders().forEach((e,t)=>{N.headers.append(t,e)}),N}function v(e,t){const r=e.headers.get("Origin")||e.headers.get("origin");return r?(t.headers.set("Access-Control-Allow-Origin",r),t.headers.set("Vary","Origin"),t.headers.set("Access-Control-Allow-Credentials","true"),t.headers.set("Access-Control-Allow-Headers","Content-Type, Authorization, Cookie"),t.headers.set("Access-Control-Allow-Methods","GET, POST, OPTIONS"),t):t}function S(e){const t=e.headers.get("Origin")||e.headers.get("origin")||"*";return new Response(null,{status:204,headers:{"Access-Control-Allow-Origin":t,"Access-Control-Allow-Credentials":"true","Access-Control-Allow-Headers":"Content-Type, Authorization, Cookie","Access-Control-Allow-Methods":"GET, POST, OPTIONS"}})}import{generateCodeVerifier as A,generateState as k}from"arctic";function b(e,t,r){if("all"===t)return!0;const n=e.headers.get("origin");if(!n)return!1;let s;try{s=new URL(n).host}catch{return!1}if(r){if(s.startsWith("localhost")||s.startsWith("127.0.0.1"))return!0}const o=new URL(e.url),i=o.host;return n===`${o.protocol}//${i}`||t.includes(s)}async function C(e,t,r,n){const s=t.providerMap.get(r);if(!s)return M({error:"Provider not found"},{status:400});const{state:o,codeVerifier:i}={state:k(),codeVerifier:A()},a=new URL(e.url),d=a.searchParams.get("redirectTo");if(d){let r;try{if(d.startsWith("//"))throw new Error("Protocol-relative URL not allowed");r=new URL(d,a.origin)}catch{return M({error:'Invalid "redirectTo" URL'},{status:400})}const n=r.host,s=n===new URL(e.url).host,o="all"===t.trustHosts||t.trustHosts.includes(n);if(("http:"===r.protocol||"https:"===r.protocol)&&!s&&!o)return M({error:"Untrusted redirect host"},{status:400})}const h=d?`${o}.${btoa(d)}`:o;let w,m=a.searchParams.get("callbackUri");!m&&s.requiresRedirectUri&&(m=`${a.origin}${t.basePath}/${r}/callback`);try{w=await s.getAuthorizationUrl(h,i,{redirectUri:m??void 0})}catch(e){console.error("Error getting authorization URL:",e),w=null}if(!w)return M({error:"Could not create authorization URL"},{status:500});const y=c(e.headers.get("Cookie")),v=new l(y,t.cookieOptions),S={maxAge:600,sameSite:t.development?"lax":"none",secure:!t.development};v.set(u,o,S),v.set(g,i,S),n&&v.set(f,n,S),m&&v.set(p,m,S);if("false"===a.searchParams.get("redirect")){const e=M({url:w.toString()});return v.toHeaders().forEach((t,r)=>{e.headers.append(r,t)}),e}const b=I(w.toString());return v.toHeaders().forEach((e,t)=>{b.headers.append(t,e)}),b}async function E(e,t,r){const n=new URL(e.url);let s=c(e.headers.get("Cookie")).get(d);if(!s){const t=e.headers.get("Authorization");t?.startsWith("Bearer ")&&(s=t.substring(7))}if(s||(s=n.searchParams.get("token")??void 0),!s)return M({error:"Unauthorized"},{status:401});if(!await t.validateSession(s))return M({error:"Unauthorized"},{status:401});n.searchParams.delete("token");return C(new Request(n.toString(),e),t,r,s)}async function U(e,t,r){let n=c(e.headers.get("Cookie")).get(d);if(!n){const t=e.headers.get("Authorization");t?.startsWith("Bearer ")&&(n=t.substring(7))}if(!n)return M({error:"Unauthorized"},{status:401});const s=await t.validateSession(n);if(!s||!s.user)return M({error:"Unauthorized"},{status:401});const o=s.accounts??[];if(o.length<=1)return M({error:"Cannot unlink the last account"},{status:400});const i=o.find(e=>e.provider===r);if(!i)return M({error:`Provider "${r}" not linked to this account`},{status:400});await t.unlinkAccount(r,i.providerAccountId);if((await t.getAccounts(s.user.id)).length>0&&s.user.email)try{await t.updateUser({id:s.user.id,email:null,emailVerified:!1})}catch(e){console.error("Failed to clear stale email after unlinking:",e)}return M({message:"Account unlinked successfully"})}async function T(e,t,r){return C(e,t,r,null)}async function H(e,t){const r=c(e.headers.get("Cookie")),n=new l(r,t.cookieOptions);n.delete(d,{sameSite:t.development?"lax":"none",secure:!t.development});const s=M({message:"Signed out"});return n.toHeaders().forEach((e,t)=>{s.headers.append(t,e)}),s}async function O(e,t){let r=c(e.headers.get("Cookie")).get(d);if(!r){const t=e.headers.get("Authorization");t?.startsWith("Bearer ")&&(r=t.substring(7))}const n=Array.from(t.providerMap.keys());if(!r)return M({...R,providers:n});try{const e=await t.validateSession(r);return e?M({...e,providers:n}):M({...R,providers:n},{status:401})}catch(e){return console.error("Error validating session:",e),M({error:"Failed to validate session"},{status:500})}}function P(e){const{basePath:t}=e;return async function(r){if("OPTIONS"===r.method)return S(r);const n=new URL(r.url);if(!n.pathname.startsWith(t))return v(r,M({error:"Not Found"},{status:404}));if("POST"===r.method&&!b(r,e.trustHosts,e.development)){if(e.development){const e=r.headers.get("origin")??"N/A";return v(r,M({error:"Forbidden",message:`Untrusted origin: '${e}'. Add this origin to 'trustHosts' in createAuth() or ensure you are using 'localhost' or '127.0.0.1' for development.`},{status:403}))}return v(r,M({error:"Forbidden"},{status:403}))}const s=n.pathname.substring(t.length).split("/").filter(Boolean),o=s[0];if(!o)return v(r,M({error:"Not Found"},{status:404}));let i;return i="GET"===r.method?"session"===o?await O(r,e):2===s.length&&"link"===s[0]?await E(r,e,s[1]):2===s.length&&"callback"===s[1]?await y(r,e,o):1===s.length?await T(r,e,o):M({error:"Not Found"},{status:404}):"POST"===r.method?1===s.length&&"signout"===o?await H(r,e):2===s.length&&"unlink"===s[0]?await U(r,e,s[1]):M({error:"Not Found"},{status:404}):M({error:"Method Not Allowed"},{status:405}),v(r,i)}}var R={user:null,session:null,accounts:null},x=class extends Error{cause;constructor(e,t){super(e),this.name="AuthError",this.cause=t}};function M(e,t={}){const r=new Headers(t.headers);return r.has("Content-Type")||r.set("Content-Type","application/json; charset=utf-8"),new Response(JSON.stringify(e),{...t,headers:r})}function I(e,t=302){return new Response(null,{status:t,headers:{Location:e}})}async function L(e){try{const t=function(e){const t=e.replace(/-/g,"+").replace(/_/g,"/"),r=(4-t.length%4)%4,n=t.padEnd(t.length+r,"=");try{const e=atob(n),t=e.length,r=new Uint8Array(t);for(let n=0;n<t;n++)r[n]=e.charCodeAt(n);return r}catch{throw new x("Invalid base64url string")}}(e),r=await crypto.subtle.importKey("pkcs8",t.slice(),{name:"ECDSA",namedCurve:"P-256"},!0,["sign"]),n=await crypto.subtle.exportKey("jwk",r);delete n.d,n.key_ops=["verify"];return{privateKey:r,publicKey:await crypto.subtle.importKey("jwk",n,{name:"ECDSA",namedCurve:"P-256"},!0,["verify"])}}catch(e){if(e instanceof x)throw e;throw new x("Invalid secret. Must be a base64url-encoded PKCS#8 private key for ES256. Use `bunx gau secret` to generate one.",e)}}async function N(r,n={}){let{algorithm:s="ES256",ttl:o,iss:i,aud:a,sub:c,privateKey:l,secret:u}=n;if("ES256"===s){if(!l){if("string"!=typeof u)throw new x("Missing secret for ES256 signing. It must be a base64url-encoded string.");({privateKey:l}=await L(u))}}else if("HS256"===s&&!u)throw new x("Missing secret for HS256 signing");const d=Math.floor(Date.now()/1e3),h={iat:d,iss:i,aud:a,sub:c,...r};null!=o&&o>0&&(h.exp=d+o);const f="HS256"===s,g=f?"HS256":"ES256",p=JSON.stringify({alg:g,typ:"JWT"}),w=JSON.stringify(h),m=e(p,w);let y;if(f){const e="string"==typeof u?(new TextEncoder).encode(u):u,t=await crypto.subtle.importKey("raw",e,{name:"HMAC",hash:"SHA-256"},!1,["sign"]);y=new Uint8Array(await crypto.subtle.sign("HMAC",t,m))}else y=new Uint8Array(await crypto.subtle.sign({name:"ECDSA",hash:"SHA-256"},l,m));return t(p,w,y)}async function F(e,t){let{algorithm:o="ES256",publicKey:i,secret:a,iss:c,aud:l}=t;if("ES256"===o&&!i){if("string"!=typeof a)throw new x("Missing secret for ES256 verification. Must be a base64url-encoded string.");({publicKey:i}=await L(a))}if("HS256"===o&&!a)throw new x("Missing secret for HS256 verification");const[u,d,h,f]=s(e),g=new r(u).algorithm();let p=!1;if("HS256"===o){if("HS256"!==g)throw new Error(`JWT algorithm is "${g}", but verifier was configured for "HS256"`);const e="string"==typeof a?(new TextEncoder).encode(a):a,t=await crypto.subtle.importKey("raw",e,{name:"HMAC",hash:"SHA-256"},!1,["sign"]);p=function(e,t){let r=e.length^t.length;const n=Math.max(e.length,t.length);for(let s=0;s<n;s++)r|=(e[s]??0)^(t[s]??0);return 0===r}(new Uint8Array(await crypto.subtle.sign("HMAC",t,f)),new Uint8Array(h))}else{if("ES256"!==g)throw new x(`JWT algorithm is "${g}", but verifier was configured for "ES256"`);const e=new Uint8Array(h);if(p=await crypto.subtle.verify({name:"ECDSA",hash:"SHA-256"},i,e,f),!p&&64===e.length)try{const t=function(e){if(64!==e.length)throw new Error("Invalid raw signature length");let t=e.slice(0,32),r=e.slice(32),n=0;for(;n<t.length-1&&0===t[n];)n++;t=t.slice(n);let s=0;for(;s<r.length-1&&0===r[s];)s++;if(r=r.slice(s),t.length>0&&128&t[0]){const e=new Uint8Array(t.length+1);e[0]=0,e.set(t,1),t=e}if(r.length>0&&128&r[0]){const e=new Uint8Array(r.length+1);e[0]=0,e.set(r,1),r=e}const o=t.length,i=r.length,a=2+o+2+i,c=new Uint8Array(2+a);return c[0]=48,c[1]=a,c[2]=2,c[3]=o,c.set(t,4),c[4+o]=2,c[5+o]=i,c.set(r,6+o),c}(e);p=await crypto.subtle.verify({name:"ECDSA",hash:"SHA-256"},i,t,f)}catch{p=!1}}if(!p)throw new x("Invalid JWT signature");const w=new n(d);if(w.hasExpiration()&&!w.verifyExpiration())throw new x("JWT expired");if(w.hasNotBefore()&&!w.verifyNotBefore())throw new x("JWT not yet valid");if(c&&d.iss!==c)throw new x("Invalid JWT issuer");if(l){const e=Array.isArray(l)?l:[l],t=d.aud?Array.isArray(d.aud)?d.aud:[d.aud]:[];if(!e.some(e=>t.includes(e)))throw new x("Invalid JWT audience")}return d}export{a as DEFAULT_COOKIE_SERIALIZE_OPTIONS,c as parseCookies,l as Cookies,u as CSRF_COOKIE_NAME,d as SESSION_COOKIE_NAME,h as SESSION_STRATEGY_COOKIE_NAME,f as LINKING_TOKEN_COOKIE_NAME,g as PKCE_COOKIE_NAME,p as CALLBACK_URI_COOKIE_NAME,w as CSRF_MAX_AGE,N as sign,F as verify,m as createAuth,y as handleCallback,v as applyCors,S as handlePreflight,b as verifyRequestOrigin,E as handleLink,U as handleUnlink,T as handleSignIn,H as handleSignOut,O as handleSession,P as createHandler,R as NULL_SESSION,x as AuthError,M as json,I as redirect};//# sourceMappingURL=chunk-WEGQGDWC.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/jwt/jwt.ts","../src/core/cookies.ts","../src/core/createAuth.ts","../src/core/handlers/callback.ts","../src/core/handlers/cors.ts","../src/oauth/utils.ts","../src/core/handlers/utils.ts","../src/core/handlers/link.ts","../src/core/handlers/login.ts","../src/core/handlers/session.ts","../src/core/handler.ts","../src/core/index.ts","../src/jwt/utils.ts"],"sourcesContent":["/// <reference types=\"node\" />\nimport {\n createJWTSignatureMessage,\n encodeJWT,\n JWSRegisteredHeaders,\n JWTRegisteredClaims,\n parseJWT,\n} from '@oslojs/jwt'\nimport { AuthError } from '../core/index'\nimport { constantTimeEqual, deriveKeysFromSecret, rawToDer } from './utils'\n\nexport type SupportedAlgorithm = 'ES256' | 'HS256'\n\ninterface CommonSignOptions {\n /** Time-to-live in seconds (exp claim). If omitted the token will not expire. */\n ttl?: number\n}\n\nexport type SignOptions\n = | ({ algorithm?: 'ES256', privateKey?: CryptoKey, secret?: string }\n & CommonSignOptions & { iss?: string, aud?: string | string[], sub?: string })\n | ({ algorithm: 'HS256', secret?: string | Uint8Array, privateKey?: never }\n & CommonSignOptions & { iss?: string, aud?: string | string[], sub?: string })\n\n/**\n * Create a signed JWT.\n * Defaults to ES256 when a privateKey is supplied. Falls back to HS256 when a secret is supplied.\n */\nexport async function sign<T extends Record<string, unknown>>(payload: T, options: SignOptions = {}): Promise<string> {\n let { algorithm = 'ES256', ttl, iss, aud, sub, privateKey, secret } = options\n\n if (algorithm === 'ES256') {\n if (!privateKey) {\n if (typeof secret !== 'string')\n throw new AuthError('Missing secret for ES256 signing. It must be a base64url-encoded string.');\n\n ({ privateKey } = await deriveKeysFromSecret(secret))\n }\n }\n else if (algorithm === 'HS256' && !secret) {\n throw new AuthError('Missing secret for HS256 signing')\n }\n\n const now = Math.floor(Date.now() / 1000)\n\n const jwtPayload: Record<string, unknown> = { iat: now, iss, aud, sub, ...payload }\n\n if (ttl != null && ttl > 0)\n jwtPayload.exp = now + ttl\n\n const isHS256 = algorithm === 'HS256'\n const alg: SupportedAlgorithm = isHS256 ? 'HS256' : 'ES256'\n\n const headerJSON = JSON.stringify({ alg, typ: 'JWT' })\n const payloadJSON = JSON.stringify(jwtPayload)\n\n const signatureMessage = createJWTSignatureMessage(headerJSON, payloadJSON)\n\n let signature: Uint8Array\n\n if (isHS256) {\n // HS256 (HMAC-SHA256)\n const secretBytes = typeof secret === 'string'\n ? new TextEncoder().encode(secret)\n : secret\n\n const cryptoKey = await crypto.subtle.importKey(\n 'raw',\n secretBytes as BufferSource,\n { name: 'HMAC', hash: 'SHA-256' },\n false,\n ['sign'],\n )\n\n signature = new Uint8Array(await crypto.subtle.sign('HMAC', cryptoKey, signatureMessage as BufferSource))\n }\n else {\n // ES256 (ECDSA-SHA256)\n // Runtimes like Bun's return the raw (r||s) signature directly, not DER-encoded.\n signature = new Uint8Array(\n await crypto.subtle.sign(\n { name: 'ECDSA', hash: 'SHA-256' },\n privateKey!,\n signatureMessage as BufferSource,\n ),\n )\n }\n\n return encodeJWT(headerJSON, payloadJSON, signature)\n}\n\nexport type VerifyOptions\n = | { algorithm?: 'ES256', publicKey?: CryptoKey, secret?: string, iss?: string, aud?: string | string[] }\n | { algorithm: 'HS256', secret?: string | Uint8Array, publicKey?: never, iss?: string, aud?: string | string[] }\n\n/**\n * Verify a JWT and return its payload when the signature is valid.\n * The algorithm is inferred from options – ES256 by default.\n * Throws when verification fails or the token is expired.\n */\nexport async function verify<T = Record<string, unknown>>(token: string, options: VerifyOptions): Promise<T> {\n let { algorithm = 'ES256', publicKey, secret, iss, aud } = options\n\n if (algorithm === 'ES256') {\n if (!publicKey) {\n if (typeof secret !== 'string')\n throw new AuthError('Missing secret for ES256 verification. Must be a base64url-encoded string.');\n\n ({ publicKey } = await deriveKeysFromSecret(secret))\n }\n }\n\n if (algorithm === 'HS256' && !secret)\n throw new AuthError('Missing secret for HS256 verification')\n\n const [header, payload, signature, signatureMessage] = parseJWT(token)\n\n const headerParams = new JWSRegisteredHeaders(header)\n const headerAlg = headerParams.algorithm()\n\n let validSignature = false\n\n // HS256 verification path\n if (algorithm === 'HS256') {\n if (headerAlg !== 'HS256')\n throw new Error(`JWT algorithm is \"${headerAlg}\", but verifier was configured for \"HS256\"`)\n\n const secretBytes = typeof secret === 'string'\n ? new TextEncoder().encode(secret)\n : secret\n\n const cryptoKey = await crypto.subtle.importKey(\n 'raw',\n secretBytes as BufferSource,\n { name: 'HMAC', hash: 'SHA-256' },\n false,\n ['sign'],\n )\n\n const expectedSig = new Uint8Array(await crypto.subtle.sign('HMAC', cryptoKey, signatureMessage as BufferSource))\n validSignature = constantTimeEqual(expectedSig, new Uint8Array(signature))\n }\n // ES256 verification path (default)\n else {\n if (headerAlg !== 'ES256')\n throw new AuthError(`JWT algorithm is \"${headerAlg}\", but verifier was configured for \"ES256\"`)\n\n const signatureBytes = new Uint8Array(signature)\n\n // Runtimes like Node.js return DER-encoded signatures. Others (Bun) return raw (r||s).\n // We try DER first, as it's more common in Node environments.\n validSignature = await crypto.subtle.verify(\n { name: 'ECDSA', hash: 'SHA-256' },\n publicKey!,\n signatureBytes as BufferSource,\n signatureMessage as BufferSource,\n )\n\n if (!validSignature && signatureBytes.length === 64) {\n // If DER verification fails and the signature is 64 bytes, it might be a raw signature.\n // Convert it to DER and try again.\n try {\n const derSig = rawToDer(signatureBytes)\n validSignature = await crypto.subtle.verify(\n { name: 'ECDSA', hash: 'SHA-256' },\n publicKey!,\n derSig as BufferSource,\n signatureMessage as BufferSource,\n )\n }\n catch {\n // rawToDer can throw if the signature is not 64 bytes, but we already checked.\n // This catch is for other unexpected errors.\n validSignature = false\n }\n }\n }\n\n if (!validSignature)\n throw new AuthError('Invalid JWT signature')\n\n const claims = new JWTRegisteredClaims(payload)\n if (claims.hasExpiration() && !claims.verifyExpiration())\n throw new AuthError('JWT expired')\n if (claims.hasNotBefore() && !claims.verifyNotBefore())\n throw new AuthError('JWT not yet valid')\n if (iss && (payload as any).iss !== iss)\n throw new AuthError('Invalid JWT issuer')\n\n if (aud) {\n const expectedAudience = Array.isArray(aud) ? aud : [aud]\n const tokenAudience = (payload as any).aud\n ? (Array.isArray((payload as any).aud) ? (payload as any).aud : [(payload as any).aud])\n : []\n\n if (!expectedAudience.some(audValue => tokenAudience.includes(audValue)))\n throw new AuthError('Invalid JWT audience')\n }\n\n return payload as T\n}\n","import type { SerializeOptions } from 'cookie'\nimport { parse, serialize } from 'cookie'\n\nexport const DEFAULT_COOKIE_SERIALIZE_OPTIONS: SerializeOptions = {\n path: '/',\n sameSite: 'lax',\n secure: true,\n httpOnly: true,\n}\n\nexport type Cookie = [string, string, SerializeOptions]\n\nexport function parseCookies(cookieHeader: string | null | undefined): Map<string, string> {\n const cookies = new Map<string, string>()\n if (cookieHeader) {\n const parsed = parse(cookieHeader)\n for (const name in parsed)\n cookies.set(name, parsed[name]!)\n }\n return cookies\n}\n\nexport class Cookies {\n #new: Cookie[] = []\n\n constructor(\n private readonly requestCookies: Map<string, string>,\n private readonly defaultOptions: SerializeOptions,\n ) {}\n\n get(name: string): string | undefined {\n return this.requestCookies.get(name)\n }\n\n set(name: string, value: string, options?: SerializeOptions): void {\n const combinedOptions = { ...this.defaultOptions, ...options }\n this.#new.push([name, value, combinedOptions])\n }\n\n delete(name: string, options?: Omit<SerializeOptions, 'expires' | 'maxAge'>): void {\n this.set(name, '', { ...options, expires: new Date(0), maxAge: 0 })\n }\n\n toHeaders(): Headers {\n const headers = new Headers()\n for (const [name, value, options] of this.#new)\n headers.append('Set-Cookie', serialize(name, value, options))\n\n return headers\n }\n}\n\nexport const CSRF_COOKIE_NAME = '__gau-csrf-token'\nexport const SESSION_COOKIE_NAME = '__gau-session-token'\nexport const SESSION_STRATEGY_COOKIE_NAME = '__gau-session-strategy'\nexport const LINKING_TOKEN_COOKIE_NAME = '__gau-linking-token'\nexport const PKCE_COOKIE_NAME = '__gau-pkce-code-verifier'\nexport const CALLBACK_URI_COOKIE_NAME = '__gau-callback-uri'\n\nexport const CSRF_MAX_AGE = 60 * 10 // 10 minutes\n","import type { SerializeOptions } from 'cookie'\nimport type { SignOptions, VerifyOptions } from '../jwt'\nimport type { OAuthProvider } from '../oauth'\nimport type { Adapter, GauSession } from './index'\nimport { sign, verify } from '../jwt'\nimport { DEFAULT_COOKIE_SERIALIZE_OPTIONS } from './cookies'\nimport { AuthError } from './index'\n\ntype ProviderId<P> = P extends OAuthProvider<infer T> ? T : never\nexport type ProviderIds<T> = T extends { providerMap: Map<infer K extends string, any> } ? K : string\n\nexport interface CreateAuthOptions<TProviders extends OAuthProvider[]> {\n /** The database adapter to use for storing users and accounts. */\n adapter: Adapter\n /** Array of OAuth providers to support. */\n providers: TProviders\n /** Base path for authentication routes (defaults to '/api/auth'). */\n basePath?: string\n /** Session management options */\n session?: {\n /** Strategy to use for sessions: 'auto' (default), 'cookie', or 'token'. */\n strategy?: 'auto' | 'cookie' | 'token'\n }\n /** Configuration for JWT signing and verification. */\n jwt?: {\n /** Signing algorithm: 'ES256' (default) or 'HS256'. */\n algorithm?: 'ES256' | 'HS256'\n /** Secret for HS256 or base64url-encoded private key for ES256 (overrides AUTH_SECRET). */\n secret?: string\n /** Issuer claim (iss) for JWTs. */\n iss?: string\n /** Audience claim (aud) for JWTs. */\n aud?: string\n /** Default time-to-live in seconds for JWTs (defaults to 1 day). */\n ttl?: number\n }\n /** Custom options for session cookies. */\n cookies?: Partial<SerializeOptions>\n /** Trusted hosts for CSRF protection: 'all' or array of hostnames (defaults to []). */\n trustHosts?: 'all' | string[]\n /** Account linking behavior: 'verifiedEmail' (default), 'always', or false. */\n autoLink?: 'verifiedEmail' | 'always' | false\n /** Optional configuration for role-based access control. */\n roles?: {\n /** Default role for newly created users. */\n defaultRole?: string\n /** Dynamically resolve the role at the moment of user creation. Return undefined to fall back to defaultRole. */\n resolveOnCreate?: (context: { providerId: string, profile: any, request: Request }) => string | undefined\n /** Roles that are considered admin-like for helper predicates. */\n adminRoles?: string[]\n /** Users that are always treated as admin for helper predicates. */\n adminUserIds?: string[]\n }\n}\n\nexport type Auth<TProviders extends OAuthProvider[] = any> = Adapter & {\n providerMap: Map<ProviderId<TProviders[number]>, TProviders[number]>\n basePath: string\n cookieOptions: SerializeOptions\n jwt: {\n ttl: number\n }\n signJWT: <U extends Record<string, unknown>>(payload: U, customOptions?: Partial<SignOptions>) => Promise<string>\n verifyJWT: <U = Record<string, unknown>>(token: string, customOptions?: Partial<VerifyOptions>) => Promise<U | null>\n createSession: (userId: string, data?: Record<string, unknown>, ttl?: number) => Promise<string>\n validateSession: (token: string) => Promise<GauSession | null>\n trustHosts: 'all' | string[]\n autoLink: 'verifiedEmail' | 'always' | false\n sessionStrategy: 'auto' | 'cookie' | 'token'\n development: boolean\n roles: {\n defaultRole: string\n resolveOnCreate?: (context: { providerId: string, profile: any, request: Request }) => string | undefined\n adminRoles: string[]\n adminUserIds: string[]\n }\n}\n\nexport function createAuth<const TProviders extends OAuthProvider[]>({\n adapter,\n providers,\n basePath = '/api/auth',\n jwt: jwtConfig = {},\n session: sessionConfig = {},\n cookies: cookieConfig = {},\n trustHosts = [],\n autoLink = 'verifiedEmail',\n roles: rolesConfig = {},\n}: CreateAuthOptions<TProviders>): Auth<TProviders> {\n const { algorithm = 'ES256', secret, iss, aud, ttl: defaultTTL = 3600 * 24 } = jwtConfig\n const cookieOptions = { ...DEFAULT_COOKIE_SERIALIZE_OPTIONS, ...cookieConfig }\n\n const sessionStrategy: 'auto' | 'cookie' | 'token' = sessionConfig.strategy ?? 'auto'\n\n if (algorithm === 'ES256' && secret !== undefined && typeof secret !== 'string')\n throw new AuthError('For ES256, the secret option must be a string.')\n\n const providerMap = new Map(providers.map(p => [p.id, p]))\n\n function buildSignOptions(custom: Partial<SignOptions> = {}): SignOptions {\n const base = { ttl: custom.ttl, iss: custom.iss ?? iss, aud: custom.aud ?? aud, sub: custom.sub }\n if (algorithm === 'HS256') {\n return { algorithm, secret: custom.secret ?? secret, ...base }\n }\n else {\n if (custom.secret !== undefined && typeof custom.secret !== 'string')\n throw new AuthError('For ES256, the secret option must be a string.')\n const esSecret = custom.secret ?? secret\n return { algorithm, privateKey: custom.privateKey, secret: esSecret, ...base }\n }\n }\n\n function buildVerifyOptions(custom: Partial<VerifyOptions> = {}): VerifyOptions {\n const base = { iss: custom.iss ?? iss, aud: custom.aud ?? aud }\n if (algorithm === 'HS256') {\n return { algorithm, secret: custom.secret ?? secret, ...base }\n }\n else {\n if (custom.secret !== undefined && typeof custom.secret !== 'string')\n throw new AuthError('For ES256, the secret option must be a string.')\n const esSecret = custom.secret ?? secret\n return { algorithm, publicKey: custom.publicKey, secret: esSecret, ...base }\n }\n }\n\n async function signJWT<U extends Record<string, unknown>>(payload: U, customOptions: Partial<SignOptions> = {}): Promise<string> {\n return sign(payload, buildSignOptions(customOptions))\n }\n\n async function verifyJWT<U = Record<string, unknown>>(token: string, customOptions: Partial<VerifyOptions> = {}): Promise<U | null> {\n const options = buildVerifyOptions(customOptions)\n try {\n return await verify<U>(token, options)\n }\n catch {\n return null\n }\n }\n\n async function createSession(userId: string, data: Record<string, unknown> = {}, ttl = defaultTTL): Promise<string> {\n const payload = { sub: userId, ...data }\n return signJWT(payload, { ttl })\n }\n\n async function validateSession(token: string): Promise<GauSession | null> {\n const payload = await verifyJWT<{ sub: string } & Record<string, unknown>>(token)\n if (!payload)\n return null\n\n const userAndAccounts = await adapter.getUserAndAccounts(payload.sub)\n if (!userAndAccounts)\n return null\n\n const { user, accounts } = userAndAccounts\n return { user, session: { id: token, ...payload }, accounts }\n }\n\n return {\n ...adapter,\n providerMap: providerMap as Map<ProviderId<TProviders[number]>, TProviders[number]>,\n basePath,\n cookieOptions,\n jwt: {\n ttl: defaultTTL,\n },\n signJWT,\n verifyJWT,\n createSession,\n validateSession,\n trustHosts,\n autoLink,\n sessionStrategy,\n development: false,\n roles: {\n defaultRole: rolesConfig.defaultRole ?? 'user',\n resolveOnCreate: rolesConfig.resolveOnCreate,\n adminRoles: rolesConfig.adminRoles ?? ['admin'],\n adminUserIds: rolesConfig.adminUserIds ?? [],\n },\n }\n}\n","import type { Auth } from '../createAuth'\nimport type { RequestLike, ResponseLike, User } from '../index'\nimport {\n CALLBACK_URI_COOKIE_NAME,\n Cookies,\n CSRF_COOKIE_NAME,\n LINKING_TOKEN_COOKIE_NAME,\n parseCookies,\n PKCE_COOKIE_NAME,\n SESSION_COOKIE_NAME,\n} from '../cookies'\nimport { json, redirect } from '../index'\n\nexport async function handleCallback(request: RequestLike, auth: Auth, providerId: string): Promise<ResponseLike> {\n const provider = auth.providerMap.get(providerId)\n if (!provider)\n return json({ error: 'Provider not found' }, { status: 400 })\n\n const url = new URL(request.url)\n const code = url.searchParams.get('code')\n const state = url.searchParams.get('state')\n\n if (!code || !state)\n return json({ error: 'Missing code or state' }, { status: 400 })\n\n const requestCookies = parseCookies(request.headers.get('Cookie'))\n const cookies = new Cookies(requestCookies, auth.cookieOptions)\n\n let savedState: string | undefined\n let redirectTo = '/'\n if (state.includes('.')) {\n const [originalSavedState, encodedRedirect] = state.split('.')\n savedState = originalSavedState\n try {\n redirectTo = atob(encodedRedirect ?? '') || '/'\n }\n catch {\n redirectTo = '/'\n }\n }\n else {\n savedState = state\n }\n\n const csrfToken = cookies.get(CSRF_COOKIE_NAME)\n\n if (!csrfToken || csrfToken !== savedState)\n return json({ error: 'Invalid CSRF token' }, { status: 403 })\n\n const codeVerifier = cookies.get(PKCE_COOKIE_NAME)\n if (!codeVerifier)\n return json({ error: 'Missing PKCE code verifier' }, { status: 400 })\n\n const callbackUri = cookies.get(CALLBACK_URI_COOKIE_NAME)\n const linkingToken = cookies.get(LINKING_TOKEN_COOKIE_NAME)\n\n if (linkingToken)\n cookies.delete(LINKING_TOKEN_COOKIE_NAME)\n\n const isLinking = !!linkingToken\n\n if (isLinking) {\n const session = await auth.validateSession(linkingToken!)\n if (!session) {\n cookies.delete(CSRF_COOKIE_NAME)\n cookies.delete(PKCE_COOKIE_NAME)\n if (callbackUri)\n cookies.delete(CALLBACK_URI_COOKIE_NAME)\n const response = redirect(redirectTo)\n cookies.toHeaders().forEach((value, key) => response.headers.append(key, value))\n return response\n }\n }\n\n const { user: providerUser, tokens } = await provider.validateCallback(code, codeVerifier, callbackUri ?? undefined)\n\n let user: User | null = null\n\n const userFromAccount = await auth.getUserByAccount(providerId, providerUser.id)\n\n if (isLinking) {\n const session = await auth.validateSession(linkingToken!)\n user = session!.user\n\n if (!user)\n return json({ error: 'User not found' }, { status: 404 })\n\n if (userFromAccount && userFromAccount.id !== user.id)\n return json({ error: 'Account already linked to another user' }, { status: 409 })\n }\n else {\n user = userFromAccount\n }\n\n if (!user) {\n const autoLink = auth.autoLink ?? 'verifiedEmail'\n const shouldLinkByEmail = providerUser.email && (\n (autoLink === 'always')\n || (autoLink === 'verifiedEmail' && providerUser.emailVerified === true)\n )\n if (shouldLinkByEmail) {\n const existingUser = await auth.getUserByEmail(providerUser.email!)\n if (existingUser) {\n // If the email is verified by the new provider, and the existing user's email is not,\n // update the user's email verification status.\n if (providerUser.emailVerified && !existingUser.emailVerified) {\n user = await auth.updateUser({\n id: existingUser.id,\n emailVerified: true,\n })\n }\n else {\n user = existingUser\n }\n }\n }\n if (!user) {\n try {\n let resolvedRole: string | undefined\n try {\n resolvedRole = auth.roles.resolveOnCreate?.({ providerId, profile: providerUser, request: request as unknown as Request })\n }\n catch (e) {\n console.error('roles.resolveOnCreate threw:', e)\n }\n\n user = await auth.createUser({\n name: providerUser.name,\n email: providerUser.email,\n image: providerUser.avatar,\n emailVerified: providerUser.emailVerified,\n role: resolvedRole ?? auth.roles.defaultRole,\n })\n }\n catch (error) {\n console.error('Failed to create user:', error)\n return json({ error: 'Failed to create user' }, { status: 500 })\n }\n }\n }\n\n // self-healing: update user's email if it's missing or unverified and the provider returns a verified email\n if (user && providerUser.email) {\n const { email: currentEmail, emailVerified: currentEmailVerified } = user\n const { email: providerEmail, emailVerified: providerEmailVerified } = providerUser\n\n const update: Partial<User> & { id: string } = { id: user.id }\n let needsUpdate = false\n\n // user has no primary email. promote the provider's email.\n if (!currentEmail) {\n update.email = providerEmail\n update.emailVerified = providerEmailVerified ?? false\n needsUpdate = true\n }\n // user has an unverified primary email, and the provider confirms this same email is verified.\n else if (\n currentEmail === providerEmail\n && providerEmailVerified === true\n && !currentEmailVerified\n ) {\n update.emailVerified = true\n needsUpdate = true\n }\n\n if (needsUpdate) {\n try {\n user = await auth.updateUser(update)\n }\n catch (error) {\n console.error('Failed to update user after sign-in:', error)\n }\n }\n }\n\n if (!userFromAccount) {\n // GitHub sometimes doesn't return these which causes arctic to throw an error\n let refreshToken: string | null\n try {\n refreshToken = tokens.refreshToken()\n }\n catch {\n refreshToken = null\n }\n\n let expiresAt: number | undefined\n try {\n const expiresAtDate = tokens.accessTokenExpiresAt()\n if (expiresAtDate)\n expiresAt = Math.floor(expiresAtDate.getTime() / 1000)\n }\n catch {\n }\n\n let idToken: string | null\n try {\n idToken = tokens.idToken()\n }\n catch {\n idToken = null\n }\n\n try {\n await auth.linkAccount({\n userId: user.id,\n provider: providerId,\n providerAccountId: providerUser.id,\n accessToken: tokens.accessToken(),\n refreshToken,\n expiresAt,\n tokenType: tokens.tokenType?.() ?? null,\n scope: tokens.scopes()?.join(' ') ?? null,\n idToken,\n })\n }\n catch (error) {\n console.error('Error linking account:', error)\n return json({ error: 'Failed to link account' }, { status: 500 })\n }\n }\n\n const sessionToken = await auth.createSession(user.id)\n\n const requestUrl = new URL(request.url)\n const redirectUrl = new URL(redirectTo, request.url)\n\n const forceToken = auth.sessionStrategy === 'token'\n const forceCookie = auth.sessionStrategy === 'cookie'\n\n const isDesktopRedirect = redirectUrl.protocol === 'gau:'\n const isMobileRedirect = requestUrl.host !== redirectUrl.host\n\n // For Tauri, we can't set a cookie on a custom protocol or a different host,\n // so we pass the token in the URL. Additionally, return a small HTML page\n // that immediately navigates to the deep-link and attempts to close the window,\n // so the external OAuth tab does not stay open.\n if (forceToken || (!forceCookie && (isDesktopRedirect || isMobileRedirect))) {\n const destination = new URL(redirectUrl)\n // Use hash instead of query param for security. The hash is not sent to the server.\n destination.hash = `token=${sessionToken}`\n\n const html = `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"utf-8\" />\n <title>Authentication Complete</title>\n <style>\n body {\n font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n background-color: #09090b;\n color: #fafafa;\n display: flex;\n justify-content: center;\n align-items: center;\n height: 100vh;\n margin: 0;\n text-align: center;\n }\n .card {\n background-color: #18181b;\n border: 1px solid #27272a;\n border-radius: 0.75rem;\n padding: 2rem;\n max-width: 320px;\n }\n h1 {\n font-size: 1.25rem;\n font-weight: 600;\n margin: 0 0 0.5rem;\n }\n p {\n margin: 0;\n color: #a1a1aa;\n }\n </style>\n <script>\n window.onload = function() {\n const url = ${JSON.stringify(destination.toString())};\n window.location.href = url;\n setTimeout(window.close, 500);\n };\n </script>\n</head>\n<body>\n <div class=\"card\">\n <h1>Authentication Successful</h1>\n <p>You can now close this window.</p>\n </div>\n</body>\n</html>`\n\n // Clear temporary cookies (CSRF/PKCE/Callback URI) so they don't linger\n cookies.delete(CSRF_COOKIE_NAME)\n cookies.delete(PKCE_COOKIE_NAME)\n if (callbackUri)\n cookies.delete(CALLBACK_URI_COOKIE_NAME)\n\n const response = new Response(html, {\n status: 200,\n headers: { 'Content-Type': 'text/html; charset=utf-8' },\n })\n cookies.toHeaders().forEach((value, key) => {\n response.headers.append(key, value)\n })\n return response\n }\n\n cookies.set(SESSION_COOKIE_NAME, sessionToken, {\n maxAge: auth.jwt.ttl,\n sameSite: auth.development ? 'lax' : 'none',\n secure: !auth.development,\n })\n cookies.delete(CSRF_COOKIE_NAME)\n cookies.delete(PKCE_COOKIE_NAME)\n if (callbackUri)\n cookies.delete(CALLBACK_URI_COOKIE_NAME)\n\n const redirectParam = url.searchParams.get('redirect')\n\n let response: Response\n if (redirectParam === 'false') {\n const accounts = await auth.getAccounts(user.id)\n response = json({ user: { ...user, accounts } })\n }\n else {\n response = redirect(redirectTo)\n }\n\n cookies.toHeaders().forEach((value, key) => {\n response.headers.append(key, value)\n })\n\n return response\n}\n","import type { RequestLike } from '../index'\n\nexport function applyCors(request: RequestLike, response: Response): Response {\n const origin = request.headers.get('Origin') || request.headers.get('origin')\n if (!origin)\n return response\n response.headers.set('Access-Control-Allow-Origin', origin)\n response.headers.set('Vary', 'Origin')\n response.headers.set('Access-Control-Allow-Credentials', 'true')\n response.headers.set('Access-Control-Allow-Headers', 'Content-Type, Authorization, Cookie')\n response.headers.set('Access-Control-Allow-Methods', 'GET, POST, OPTIONS')\n return response\n}\n\nexport function handlePreflight(request: RequestLike): Response {\n const origin = request.headers.get('Origin') || request.headers.get('origin') || '*'\n return new Response(null, {\n status: 204,\n headers: {\n 'Access-Control-Allow-Origin': origin,\n 'Access-Control-Allow-Credentials': 'true',\n 'Access-Control-Allow-Headers': 'Content-Type, Authorization, Cookie',\n 'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',\n },\n })\n}\n","import { generateCodeVerifier, generateState } from 'arctic'\n\nexport function createOAuthUris() {\n const state = generateState()\n const codeVerifier = generateCodeVerifier()\n\n return {\n state,\n codeVerifier,\n }\n}\n","import type { Auth } from '../createAuth'\nimport type { RequestLike, ResponseLike } from '../index'\nimport { createOAuthUris } from '../../oauth/utils'\nimport {\n CALLBACK_URI_COOKIE_NAME,\n Cookies,\n CSRF_COOKIE_NAME,\n CSRF_MAX_AGE,\n LINKING_TOKEN_COOKIE_NAME,\n parseCookies,\n PKCE_COOKIE_NAME,\n} from '../cookies'\nimport { json, redirect } from '../index'\n\nexport function verifyRequestOrigin(request: RequestLike, trustHosts: 'all' | string[], development: boolean): boolean {\n if (trustHosts === 'all')\n return true\n\n const origin = request.headers.get('origin')\n\n if (!origin)\n return false\n\n let originHost: string\n try {\n originHost = new URL(origin).host\n }\n catch {\n return false\n }\n\n if (development) {\n const isLocal = originHost.startsWith('localhost') || originHost.startsWith('127.0.0.1')\n if (isLocal)\n return true\n }\n\n const requestUrl = new URL(request.url)\n const requestHost = requestUrl.host\n const requestOrigin = `${requestUrl.protocol}//${requestHost}`\n\n if (origin === requestOrigin)\n return true\n\n return trustHosts.includes(originHost)\n}\n\nexport async function prepareOAuthRedirect(\n request: RequestLike,\n auth: Auth,\n providerId: string,\n linkingToken: string | null,\n): Promise<ResponseLike> {\n const provider = auth.providerMap.get(providerId)\n if (!provider)\n return json({ error: 'Provider not found' }, { status: 400 })\n\n const { state: originalState, codeVerifier } = createOAuthUris()\n const url = new URL(request.url)\n const redirectTo = url.searchParams.get('redirectTo')\n\n if (redirectTo) {\n let parsedRedirect: URL\n try {\n if (redirectTo.startsWith('//'))\n throw new Error('Protocol-relative URL not allowed')\n parsedRedirect = new URL(redirectTo, url.origin)\n }\n catch {\n return json({ error: 'Invalid \"redirectTo\" URL' }, { status: 400 })\n }\n\n const redirectHost = parsedRedirect.host\n const currentHost = new URL(request.url).host\n\n const isSameHost = redirectHost === currentHost\n const isTrusted = auth.trustHosts === 'all' || auth.trustHosts.includes(redirectHost)\n const isHttp = parsedRedirect.protocol === 'http:' || parsedRedirect.protocol === 'https:'\n\n if (isHttp && !isSameHost && !isTrusted)\n return json({ error: 'Untrusted redirect host' }, { status: 400 })\n }\n\n const state = redirectTo ? `${originalState}.${btoa(redirectTo)}` : originalState\n let callbackUri = url.searchParams.get('callbackUri')\n if (!callbackUri && provider.requiresRedirectUri)\n callbackUri = `${url.origin}${auth.basePath}/${providerId}/callback`\n\n let authUrl: URL | null\n try {\n authUrl = await provider.getAuthorizationUrl(state, codeVerifier, {\n redirectUri: callbackUri ?? undefined,\n })\n }\n catch (error) {\n console.error('Error getting authorization URL:', error)\n authUrl = null\n }\n\n if (!authUrl)\n return json({ error: 'Could not create authorization URL' }, { status: 500 })\n\n const requestCookies = parseCookies(request.headers.get('Cookie'))\n const cookies = new Cookies(requestCookies, auth.cookieOptions)\n\n const temporaryCookieOptions = {\n maxAge: CSRF_MAX_AGE,\n sameSite: auth.development ? 'lax' : 'none',\n secure: !auth.development,\n } as const\n\n cookies.set(CSRF_COOKIE_NAME, originalState, temporaryCookieOptions)\n cookies.set(PKCE_COOKIE_NAME, codeVerifier, temporaryCookieOptions)\n if (linkingToken)\n cookies.set(LINKING_TOKEN_COOKIE_NAME, linkingToken, temporaryCookieOptions)\n\n if (callbackUri)\n cookies.set(CALLBACK_URI_COOKIE_NAME, callbackUri, temporaryCookieOptions)\n\n const redirectParam = url.searchParams.get('redirect')\n\n if (redirectParam === 'false') {\n const response = json({ url: authUrl.toString() })\n cookies.toHeaders().forEach((value, key) => {\n response.headers.append(key, value)\n })\n return response\n }\n\n const response = redirect(authUrl.toString())\n cookies.toHeaders().forEach((value, key) => {\n response.headers.append(key, value)\n })\n\n return response\n}\n","import type { Auth } from '../createAuth'\nimport type { RequestLike, ResponseLike } from '../index'\nimport { parseCookies, SESSION_COOKIE_NAME } from '../cookies'\nimport { json } from '../index'\nimport { prepareOAuthRedirect } from './utils'\n\nexport async function handleLink(request: RequestLike, auth: Auth, providerId: string): Promise<ResponseLike> {\n const url = new URL(request.url)\n const requestCookies = parseCookies(request.headers.get('Cookie'))\n let sessionToken = requestCookies.get(SESSION_COOKIE_NAME)\n\n if (!sessionToken) {\n const authHeader = request.headers.get('Authorization')\n if (authHeader?.startsWith('Bearer '))\n sessionToken = authHeader.substring(7)\n }\n\n if (!sessionToken)\n sessionToken = url.searchParams.get('token') ?? undefined\n\n if (!sessionToken)\n return json({ error: 'Unauthorized' }, { status: 401 })\n\n const session = await auth.validateSession(sessionToken)\n if (!session)\n return json({ error: 'Unauthorized' }, { status: 401 })\n\n url.searchParams.delete('token')\n const cleanRequest = new Request(url.toString(), request as Request)\n\n return prepareOAuthRedirect(cleanRequest, auth, providerId, sessionToken)\n}\n\nexport async function handleUnlink(request: RequestLike, auth: Auth, providerId: string): Promise<ResponseLike> {\n const requestCookies = parseCookies(request.headers.get('Cookie'))\n let sessionToken = requestCookies.get(SESSION_COOKIE_NAME)\n\n if (!sessionToken) {\n const authHeader = request.headers.get('Authorization')\n if (authHeader?.startsWith('Bearer '))\n sessionToken = authHeader.substring(7)\n }\n\n if (!sessionToken)\n return json({ error: 'Unauthorized' }, { status: 401 })\n\n const session = await auth.validateSession(sessionToken)\n if (!session || !session.user)\n return json({ error: 'Unauthorized' }, { status: 401 })\n\n const accounts = session.accounts ?? []\n\n if (accounts.length <= 1)\n return json({ error: 'Cannot unlink the last account' }, { status: 400 })\n\n const accountToUnlink = accounts.find(a => a.provider === providerId)\n if (!accountToUnlink)\n return json({ error: `Provider \"${providerId}\" not linked to this account` }, { status: 400 })\n\n await auth.unlinkAccount(providerId, accountToUnlink.providerAccountId)\n\n const remainingAccounts = await auth.getAccounts(session.user.id)\n\n // if there are remaining accounts, we need to potentially update the user's primary info\n // TODO: for now we just clear the email\n if (remainingAccounts.length > 0 && session.user.email) {\n try {\n await auth.updateUser({\n id: session.user.id,\n email: null,\n emailVerified: false,\n })\n }\n catch (error) {\n console.error('Failed to clear stale email after unlinking:', error)\n }\n }\n\n return json({ message: 'Account unlinked successfully' })\n}\n","import type { Auth } from '../createAuth'\nimport type { RequestLike, ResponseLike } from '../index'\nimport { Cookies, parseCookies, SESSION_COOKIE_NAME } from '../cookies'\n\nimport { json } from '../index'\nimport { prepareOAuthRedirect } from './utils'\n\nexport async function handleSignIn(request: RequestLike, auth: Auth, providerId: string): Promise<ResponseLike> {\n return prepareOAuthRedirect(request, auth, providerId, null)\n}\n\nexport async function handleSignOut(request: RequestLike, auth: Auth): Promise<ResponseLike> {\n const requestCookies = parseCookies(request.headers.get('Cookie'))\n const cookies = new Cookies(requestCookies, auth.cookieOptions)\n cookies.delete(SESSION_COOKIE_NAME, {\n sameSite: auth.development ? 'lax' : 'none',\n secure: !auth.development,\n })\n\n const response = json({ message: 'Signed out' })\n cookies.toHeaders().forEach((value, key) => {\n response.headers.append(key, value)\n })\n\n return response\n}\n","import type { Auth } from '../createAuth'\nimport type { RequestLike, ResponseLike } from '../index'\nimport { parseCookies, SESSION_COOKIE_NAME } from '../cookies'\nimport { json, NULL_SESSION } from '../index'\n\nexport async function handleSession(request: RequestLike, auth: Auth): Promise<ResponseLike> {\n const rawCookieHeader = request.headers.get('Cookie')\n const requestCookies = parseCookies(rawCookieHeader)\n let sessionToken = requestCookies.get(SESSION_COOKIE_NAME)\n\n if (!sessionToken) {\n const authHeader = request.headers.get('Authorization')\n if (authHeader?.startsWith('Bearer '))\n sessionToken = authHeader.substring(7)\n }\n\n const providers = Array.from(auth.providerMap.keys())\n\n if (!sessionToken)\n return json({ ...NULL_SESSION, providers })\n\n try {\n const sessionData = await auth.validateSession(sessionToken)\n\n if (!sessionData)\n return json({ ...NULL_SESSION, providers }, { status: 401 })\n\n return json({ ...sessionData, providers })\n }\n catch (error) {\n console.error('Error validating session:', error)\n return json({ error: 'Failed to validate session' }, { status: 500 })\n }\n}\n","import type { Auth } from './createAuth'\nimport type { RequestLike, ResponseLike } from './index'\nimport {\n applyCors,\n handleCallback,\n handleLink,\n handlePreflight,\n handleSession,\n handleSignIn,\n handleSignOut,\n handleUnlink,\n verifyRequestOrigin,\n} from './handlers'\nimport { json } from './index'\n\nexport function createHandler(auth: Auth): (request: RequestLike) => Promise<ResponseLike> {\n const { basePath } = auth\n\n return async function (request: RequestLike): Promise<ResponseLike> {\n // Handle preflight requests early\n if (request.method === 'OPTIONS')\n return handlePreflight(request)\n\n const url = new URL(request.url)\n if (!url.pathname.startsWith(basePath))\n return applyCors(request, json({ error: 'Not Found' }, { status: 404 }))\n\n if (request.method === 'POST' && !verifyRequestOrigin(request, auth.trustHosts, auth.development)) {\n if (auth.development) {\n const origin = request.headers.get('origin') ?? 'N/A'\n const message = `Untrusted origin: '${origin}'. Add this origin to 'trustHosts' in createAuth() or ensure you are using 'localhost' or '127.0.0.1' for development.`\n return applyCors(request, json({ error: 'Forbidden', message }, { status: 403 }))\n }\n return applyCors(request, json({ error: 'Forbidden' }, { status: 403 }))\n }\n\n const path = url.pathname.substring(basePath.length)\n const parts = path.split('/').filter(Boolean)\n const action = parts[0]\n\n if (!action)\n return applyCors(request, json({ error: 'Not Found' }, { status: 404 }))\n\n let response: ResponseLike\n\n if (request.method === 'GET') {\n if (action === 'session')\n response = await handleSession(request, auth)\n else if (parts.length === 2 && parts[0] === 'link')\n response = await handleLink(request, auth, parts[1] as string)\n else if (parts.length === 2 && parts[1] === 'callback')\n response = await handleCallback(request, auth, action)\n else if (parts.length === 1)\n response = await handleSignIn(request, auth, action)\n else\n response = json({ error: 'Not Found' }, { status: 404 })\n }\n else if (request.method === 'POST') {\n if (parts.length === 1 && action === 'signout')\n response = await handleSignOut(request, auth)\n else if (parts.length === 2 && parts[0] === 'unlink')\n response = await handleUnlink(request, auth, parts[1] as string)\n else\n response = json({ error: 'Not Found' }, { status: 404 })\n }\n else {\n response = json({ error: 'Method Not Allowed' }, { status: 405 })\n }\n\n return applyCors(request, response as Response)\n }\n}\n","export interface RequestLike {\n /** Absolute or relative URL */\n readonly url: string\n /** Upper-case HTTP method (e.g. `GET`) */\n readonly method: string\n /** All HTTP headers – mutable so adapters can append */\n readonly headers: Headers\n /** Lazily parse the body as JSON */\n json: <T = unknown>() => Promise<T>\n /** Raw text body */\n text: () => Promise<string>\n /** FormData helper (for `application/x-www-form-urlencoded` or `multipart/form-data`) */\n formData: () => Promise<FormData>\n}\n\nexport interface ResponseLike {\n readonly status: number\n readonly headers: Headers\n readonly body?: BodyInit | null\n json: <T = unknown>() => Promise<T>\n text: () => Promise<string>\n}\n\nexport interface User {\n id: string\n name?: string | null\n email?: string | null\n emailVerified?: boolean | null\n image?: string | null\n role?: string | null\n}\n\nexport interface Session {\n id: string\n sub: string\n [key: string]: unknown\n}\n\nexport interface GauSession<TProviders extends string = string> {\n user: User | null\n session: Session | null\n accounts?: Account[] | null\n providers?: TProviders[]\n}\n\nexport const NULL_SESSION = {\n user: null,\n session: null,\n accounts: null,\n} as const\n\nexport interface NewUser extends Omit<User, 'id' | 'accounts'> {\n id?: string\n}\n\nexport interface Account {\n userId: string\n provider: string\n providerAccountId: string\n type?: string // e.g. \"oauth\"\n accessToken?: string | null\n refreshToken?: string | null\n expiresAt?: number | null // epoch seconds\n idToken?: string | null\n scope?: string | null\n tokenType?: string | null\n sessionState?: string | null\n}\n\nexport interface NewAccount extends Account {}\n\nexport interface Adapter {\n getUser: (id: string) => Promise<User | null>\n getUserByEmail: (email: string) => Promise<User | null>\n getUserByAccount: (provider: string, providerAccountId: string) => Promise<User | null>\n getAccounts: (userId: string) => Promise<Account[]>\n getUserAndAccounts: (userId: string) => Promise<{ user: User, accounts: Account[] } | null>\n createUser: (data: NewUser) => Promise<User>\n linkAccount: (data: NewAccount) => Promise<void>\n unlinkAccount: (provider: string, providerAccountId: string) => Promise<void>\n updateUser: (data: Partial<User> & { id: string }) => Promise<User>\n deleteUser: (id: string) => Promise<void>\n}\n\nexport class AuthError extends Error {\n override readonly cause?: unknown\n constructor(message: string, cause?: unknown) {\n super(message)\n this.name = 'AuthError'\n this.cause = cause\n }\n}\n\nexport function json<T>(data: T, init: ResponseInit = {}): Response {\n const headers = new Headers(init.headers)\n if (!headers.has('Content-Type'))\n headers.set('Content-Type', 'application/json; charset=utf-8')\n return new Response(JSON.stringify(data), { ...init, headers })\n}\n\nexport function redirect(url: string, status: 302 | 303 = 302): Response {\n return new Response(null, {\n status,\n headers: {\n Location: url,\n },\n })\n}\n\nexport * from './cookies'\nexport * from './createAuth'\nexport * from './handler'\n","import { AuthError } from '../core/index'\n\nexport function constantTimeEqual(a: Uint8Array, b: Uint8Array): boolean {\n let diff = a.length ^ b.length\n const len = Math.max(a.length, b.length)\n for (let i = 0; i < len; i++)\n diff |= (a[i] ?? 0) ^ (b[i] ?? 0)\n\n return diff === 0\n}\n\nfunction base64UrlToArray(base64Url: string): Uint8Array {\n const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/')\n const padLength = (4 - (base64.length % 4)) % 4\n const padded = base64.padEnd(base64.length + padLength, '=')\n try {\n const binary_string = atob(padded)\n const len = binary_string.length\n const bytes = new Uint8Array(len)\n for (let i = 0; i < len; i++)\n bytes[i] = binary_string.charCodeAt(i)\n\n return bytes\n }\n catch {\n throw new AuthError('Invalid base64url string')\n }\n}\n\nexport async function deriveKeysFromSecret(secret: string): Promise<{ privateKey: CryptoKey, publicKey: CryptoKey }> {\n try {\n const secretBytes = base64UrlToArray(secret)\n const privateKey = await crypto.subtle.importKey(\n 'pkcs8',\n secretBytes.slice(),\n { name: 'ECDSA', namedCurve: 'P-256' },\n true,\n ['sign'],\n )\n\n const jwk = await crypto.subtle.exportKey('jwk', privateKey)\n delete jwk.d\n jwk.key_ops = ['verify']\n\n const publicKey = await crypto.subtle.importKey(\n 'jwk',\n jwk,\n { name: 'ECDSA', namedCurve: 'P-256' },\n true,\n ['verify'],\n )\n return { privateKey, publicKey }\n }\n catch (error) {\n if (error instanceof AuthError)\n throw error\n throw new AuthError('Invalid secret. Must be a base64url-encoded PKCS#8 private key for ES256. Use `bunx gau secret` to generate one.', error)\n }\n}\n\n/**\n * Convert JWS raw signature (r || s) to DER-encoded format for WebCrypto.\n */\nexport function rawToDer(raw: Uint8Array): Uint8Array {\n if (raw.length !== 64)\n throw new Error('Invalid raw signature length')\n\n let r = raw.slice(0, 32)\n let s = raw.slice(32)\n\n let rOffset = 0\n while (rOffset < r.length - 1 && r[rOffset] === 0) rOffset++\n r = r.slice(rOffset)\n\n let sOffset = 0\n while (sOffset < s.length - 1 && s[sOffset] === 0) sOffset++\n s = s.slice(sOffset)\n\n if (r.length > 0 && r[0]! & 0x80) {\n const rPadded = new Uint8Array(r.length + 1)\n rPadded[0] = 0\n rPadded.set(r, 1)\n r = rPadded\n }\n if (s.length > 0 && s[0]! & 0x80) {\n const sPadded = new Uint8Array(s.length + 1)\n sPadded[0] = 0\n sPadded.set(s, 1)\n s = sPadded\n }\n\n const rLength = r.length\n const sLength = s.length\n const totalLength = 2 + rLength + 2 + sLength\n\n const der = new Uint8Array(2 + totalLength)\n der[0] = 0x30 // SEQUENCE\n der[1] = totalLength\n der[2] = 0x02 // INTEGER\n der[3] = rLength\n der.set(r, 4)\n der[4 + rLength] = 0x02 // INTEGER\n der[5 + rLength] = sLength\n der.set(s, 6 + rLength)\n\n return der\n}\n"],"mappings":"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","names":["response","response"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{DrizzleAdapter as o}from"../../../chunk-
|
|
1
|
+
import{DrizzleAdapter as o}from"../../../chunk-TLWTWCXQ.js";export{o as DrizzleAdapter};//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sqlite.d.ts","sourceRoot":"","sources":["../../../../src/adapters/drizzle/sqlite.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAsC,KAAK,EAAE,MAAM,aAAa,CAAA;AACvF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AACjE,OAAO,KAAK,EAAW,OAAO,EAA6B,MAAM,kBAAkB,CAAA;AAInF,MAAM,MAAM,UAAU,GAAG,KAAK,GAAG;IAC/B,EAAE,EAAE,SAAS,CAAA;IACb,IAAI,EAAE,SAAS,CAAA;IACf,KAAK,EAAE,SAAS,CAAA;IAChB,KAAK,EAAE,SAAS,CAAA;IAChB,aAAa,EAAE,SAAS,CAAA;IACxB,SAAS,EAAE,SAAS,CAAA;IACpB,SAAS,EAAE,SAAS,CAAA;CACrB,CAAA;AAED,MAAM,MAAM,aAAa,GAAG,KAAK,GAAG;IAClC,MAAM,EAAE,SAAS,CAAA;IACjB,QAAQ,EAAE,SAAS,CAAA;IACnB,iBAAiB,EAAE,SAAS,CAAA;CAC7B,CAAA;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,EAAE,SAAS,kBAAkB,CAAC,MAAM,GAAG,OAAO,EAAE,GAAG,EAAE,GAAG,CAAC,EACzD,CAAC,SAAS,UAAU,EACpB,CAAC,SAAS,aAAa,EACvB,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,OAAO,
|
|
1
|
+
{"version":3,"file":"sqlite.d.ts","sourceRoot":"","sources":["../../../../src/adapters/drizzle/sqlite.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAsC,KAAK,EAAE,MAAM,aAAa,CAAA;AACvF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AACjE,OAAO,KAAK,EAAW,OAAO,EAA6B,MAAM,kBAAkB,CAAA;AAInF,MAAM,MAAM,UAAU,GAAG,KAAK,GAAG;IAC/B,EAAE,EAAE,SAAS,CAAA;IACb,IAAI,EAAE,SAAS,CAAA;IACf,KAAK,EAAE,SAAS,CAAA;IAChB,KAAK,EAAE,SAAS,CAAA;IAChB,aAAa,EAAE,SAAS,CAAA;IACxB,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB,SAAS,EAAE,SAAS,CAAA;IACpB,SAAS,EAAE,SAAS,CAAA;CACrB,CAAA;AAED,MAAM,MAAM,aAAa,GAAG,KAAK,GAAG;IAClC,MAAM,EAAE,SAAS,CAAA;IACjB,QAAQ,EAAE,SAAS,CAAA;IACnB,iBAAiB,EAAE,SAAS,CAAA;CAC7B,CAAA;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,EAAE,SAAS,kBAAkB,CAAC,MAAM,GAAG,OAAO,EAAE,GAAG,EAAE,GAAG,CAAC,EACzD,CAAC,SAAS,UAAU,EACpB,CAAC,SAAS,aAAa,EACvB,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,OAAO,CAiIxC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{MemoryAdapter as o}from"../../chunk-
|
|
1
|
+
import{MemoryAdapter as o}from"../../chunk-UVM2UHAF.js";import{DrizzleAdapter as r}from"../../chunk-TLWTWCXQ.js";export{r as DrizzleAdapter,o as MemoryAdapter};//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/adapters/memory/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAW,OAAO,EAA6B,MAAM,kBAAkB,CAAA;AAWnF,wBAAgB,aAAa,IAAI,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/adapters/memory/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAW,OAAO,EAA6B,MAAM,kBAAkB,CAAA;AAWnF,wBAAgB,aAAa,IAAI,OAAO,CAwFvC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{MemoryAdapter as o}from"../../../chunk-
|
|
1
|
+
import{MemoryAdapter as o}from"../../../chunk-UVM2UHAF.js";export{o as MemoryAdapter};//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/client/solid/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAChF,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAOzD,UAAU,gBAAgB,CAAC,KAAK,GAAG,OAAO;IACxC,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;IACjD,MAAM,EAAE,CAAC,QAAQ,EAAE,WAAW,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC,EAAE;QAAE,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IAC1F,WAAW,EAAE,CAAC,QAAQ,EAAE,WAAW,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC,EAAE;QAAE,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IAC/F,aAAa,EAAE,CAAC,QAAQ,EAAE,WAAW,CAAC,KAAK,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IAC9D,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAC7B;AAID,wBAAgB,YAAY,CAAC,KAAK,CAAC,KAAK,GAAG,OAAO,EAAE,KAAK,EAAE,WAAW,GAAG;IAAE,IAAI,CAAC,EAAE,KAAK,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,kCAmIhJ;AAED,wBAAgB,OAAO,CAAC,KAAK,CAAC,KAAK,GAAG,OAAO,KAAK,gBAAgB,CAAC,KAAK,CAAC,CAKxE;AAED,wBAAgB,SAAS,CAAC,KAAK,CAAC,KAAK,GAAG,OAAO,EAC7C,IAAI,EAAE,CAAC,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,UAAU,EACvE,kBAAkB,CAAC,EAAE,CAAC,MAAM,UAAU,CAAC,GAAG,MAAM,GAC/C,aAAa,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/client/solid/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAChF,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAOzD,UAAU,gBAAgB,CAAC,KAAK,GAAG,OAAO;IACxC,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;IACjD,MAAM,EAAE,CAAC,QAAQ,EAAE,WAAW,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC,EAAE;QAAE,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IAC1F,WAAW,EAAE,CAAC,QAAQ,EAAE,WAAW,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC,EAAE;QAAE,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IAC/F,aAAa,EAAE,CAAC,QAAQ,EAAE,WAAW,CAAC,KAAK,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IAC9D,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAC7B;AAID,wBAAgB,YAAY,CAAC,KAAK,CAAC,KAAK,GAAG,OAAO,EAAE,KAAK,EAAE,WAAW,GAAG;IAAE,IAAI,CAAC,EAAE,KAAK,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,kCAmIhJ;AAED,wBAAgB,OAAO,CAAC,KAAK,CAAC,KAAK,GAAG,OAAO,KAAK,gBAAgB,CAAC,KAAK,CAAC,CAKxE;AAED,wBAAgB,SAAS,CAAC,KAAK,CAAC,KAAK,GAAG,OAAO,EAC7C,IAAI,EAAE,CAAC,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,UAAU,EACvE,kBAAkB,CAAC,EAAE,CAAC,MAAM,UAAU,CAAC,GAAG,MAAM,GAC/C,aAAa,CAyBf"}
|
|
@@ -234,11 +234,17 @@ function Protected(page, fallbackOrRedirect) {
|
|
|
234
234
|
const isRedirectMode = typeof fallbackOrRedirect === "string" || fallbackOrRedirect === void 0;
|
|
235
235
|
const redirectTo = isRedirectMode ? fallbackOrRedirect ?? "/" : void 0;
|
|
236
236
|
const Fallback = !isRedirectMode ? fallbackOrRedirect : void 0;
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
237
|
+
const Redirect = () => {
|
|
238
|
+
onMount(() => {
|
|
239
|
+
if (!isServer && redirectTo)
|
|
240
|
+
window.location.replace(redirectTo);
|
|
241
|
+
});
|
|
242
|
+
return null;
|
|
243
|
+
};
|
|
244
|
+
return <Show
|
|
245
|
+
when={auth.session().user}
|
|
246
|
+
fallback={isRedirectMode ? <Redirect /> : Fallback ? <Fallback /> : null}
|
|
247
|
+
>
|
|
242
248
|
{page(auth.session)}
|
|
243
249
|
</Show>;
|
|
244
250
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/client/svelte/index.svelte.ts","../../../../src/core/cookies.ts","../../../../src/jwt/jwt.ts","../../../../src/oauth/utils.ts","../../../../src/core/index.ts","../../../../src/runtimes/tauri/index.ts","../../../../src/client/token.ts"],"sourcesContent":["import type { GauSession, ProviderIds } from '../../core'\nimport { BROWSER } from 'esm-env'\nimport { getContext, setContext } from 'svelte'\nimport { NULL_SESSION } from '../../core'\nimport { handleTauriDeepLink, isTauri, linkAccountWithTauri, setupTauriListener, signInWithTauri } from '../../runtimes/tauri'\nimport { clearSessionToken, getSessionToken, storeSessionToken } from '../token'\n\ninterface AuthContextValue<TAuth = unknown> {\n session: GauSession<ProviderIds<TAuth>>\n signIn: (provider: ProviderIds<TAuth>, options?: { redirectTo?: string }) => Promise<void>\n linkAccount: (provider: ProviderIds<TAuth>, options?: { redirectTo?: string }) => Promise<void>\n unlinkAccount: (provider: ProviderIds<TAuth>) => Promise<void>\n signOut: () => Promise<void>\n}\n\nconst AUTH_CONTEXT_KEY = Symbol('gau-auth')\n\nexport function createSvelteAuth<const TAuth = unknown>({\n baseUrl = '/api/auth',\n scheme = 'gau',\n redirectTo: defaultRedirectTo,\n}: {\n baseUrl?: string\n scheme?: string\n redirectTo?: string\n} = {}) {\n type CurrentSession = GauSession<ProviderIds<TAuth>>\n let session = $state<CurrentSession>({ ...NULL_SESSION, providers: [] })\n\n async function fetchSession() {\n if (!BROWSER) {\n session = { ...NULL_SESSION, providers: [] }\n return\n }\n\n const token = getSessionToken()\n const headers = token ? { Authorization: `Bearer ${token}` } : undefined\n const res = await fetch(`${baseUrl}/session`, token ? { headers } : { credentials: 'include' })\n\n const contentType = res.headers.get('content-type')\n if (contentType?.includes('application/json')) {\n session = await res.json()\n }\n else {\n session = {\n ...NULL_SESSION,\n providers: [] as ProviderIds<TAuth>[],\n }\n }\n }\n\n async function signIn(provider: ProviderIds<TAuth>, { redirectTo }: { redirectTo?: string } = {}) {\n let finalRedirectTo = redirectTo ?? defaultRedirectTo\n if (isTauri) {\n await signInWithTauri(provider as string, baseUrl, scheme, finalRedirectTo)\n }\n else {\n if (!finalRedirectTo && BROWSER)\n finalRedirectTo = window.location.origin\n\n const query = finalRedirectTo ? `?redirectTo=${encodeURIComponent(finalRedirectTo)}` : ''\n window.location.href = `${baseUrl}/${provider as string}${query}`\n }\n }\n\n async function linkAccount(provider: ProviderIds<TAuth>, { redirectTo }: { redirectTo?: string } = {}) {\n if (isTauri) {\n await linkAccountWithTauri(provider as string, baseUrl, scheme, redirectTo)\n return\n }\n\n let finalRedirectTo = redirectTo ?? defaultRedirectTo\n if (!finalRedirectTo && BROWSER)\n finalRedirectTo = window.location.href\n\n const query = finalRedirectTo ? `?redirectTo=${encodeURIComponent(finalRedirectTo)}` : ''\n const linkUrl = `${baseUrl}/link/${provider as string}${query}${query ? '&' : '?'}redirect=false`\n\n const token = getSessionToken()\n\n const fetchOptions: RequestInit = token\n ? { headers: { Authorization: `Bearer ${token}` } }\n : { credentials: 'include' }\n\n const res = await fetch(linkUrl, fetchOptions)\n if (res.redirected) {\n window.location.href = res.url\n }\n else {\n try {\n const data = await res.json()\n if (data.url)\n window.location.href = data.url\n }\n catch (e) {\n console.error('Failed to parse response from link endpoint', e)\n }\n }\n }\n\n async function unlinkAccount(provider: ProviderIds<TAuth>) {\n const token = getSessionToken()\n const fetchOptions: RequestInit = token\n ? { headers: { Authorization: `Bearer ${token}` } }\n : { credentials: 'include' }\n\n const res = await fetch(`${baseUrl}/unlink/${provider as string}`, {\n method: 'POST',\n ...fetchOptions,\n })\n\n if (res.ok)\n await fetchSession()\n else\n console.error('Failed to unlink account', await res.json())\n }\n\n async function signOut() {\n clearSessionToken()\n const token = getSessionToken()\n const headers = token ? { Authorization: `Bearer ${token}` } : undefined\n await fetch(`${baseUrl}/signout`, token ? { method: 'POST', headers } : { method: 'POST', credentials: 'include' })\n await fetchSession()\n }\n\n if (BROWSER) {\n const hash = new URL(window.location.href).hash.substring(1)\n const params = new URLSearchParams(hash)\n const tokenFromUrl = params.get('token')\n\n if (tokenFromUrl) {\n storeSessionToken(tokenFromUrl)\n void (async () => {\n try {\n // @ts-expect-error - SvelteKit-only\n const { replaceState } = await import('$app/navigation')\n await replaceState(window.location.pathname + window.location.search, {})\n }\n catch {\n window.history.replaceState(null, '', window.location.pathname + window.location.search)\n }\n await fetchSession()\n })()\n }\n else {\n fetchSession()\n }\n }\n\n $effect(() => {\n if (!BROWSER || !isTauri)\n return\n\n let cleanup: (() => void) | void\n let disposed = false\n\n setupTauriListener(async (url) => {\n handleTauriDeepLink(url, baseUrl, scheme, async (token) => {\n storeSessionToken(token)\n await fetchSession()\n })\n }).then((unlisten) => {\n if (disposed)\n unlisten?.()\n else\n cleanup = unlisten\n })\n\n return () => {\n disposed = true\n cleanup?.()\n }\n })\n\n const contextValue: AuthContextValue<TAuth> = {\n get session() {\n return session\n },\n signIn: signIn as (provider: ProviderIds<TAuth>, options?: { redirectTo?: string }) => Promise<void>,\n linkAccount: linkAccount as (provider: ProviderIds<TAuth>, options?: { redirectTo?: string }) => Promise<void>,\n unlinkAccount: unlinkAccount as (provider: ProviderIds<TAuth>) => Promise<void>,\n signOut,\n }\n\n setContext(AUTH_CONTEXT_KEY, contextValue)\n}\n\nexport function useAuth<const TAuth = unknown>(): AuthContextValue<TAuth> {\n const context = getContext<AuthContextValue<TAuth>>(AUTH_CONTEXT_KEY)\n if (!context)\n throw new Error('useAuth must be used within an AuthProvider')\n\n return context\n}\n","import type { SerializeOptions } from 'cookie'\nimport { parse, serialize } from 'cookie'\n\nexport const DEFAULT_COOKIE_SERIALIZE_OPTIONS: SerializeOptions = {\n path: '/',\n sameSite: 'lax',\n secure: true,\n httpOnly: true,\n}\n\nexport type Cookie = [string, string, SerializeOptions]\n\nexport function parseCookies(cookieHeader: string | null | undefined): Map<string, string> {\n const cookies = new Map<string, string>()\n if (cookieHeader) {\n const parsed = parse(cookieHeader)\n for (const name in parsed)\n cookies.set(name, parsed[name]!)\n }\n return cookies\n}\n\nexport class Cookies {\n #new: Cookie[] = []\n\n constructor(\n private readonly requestCookies: Map<string, string>,\n private readonly defaultOptions: SerializeOptions,\n ) {}\n\n get(name: string): string | undefined {\n return this.requestCookies.get(name)\n }\n\n set(name: string, value: string, options?: SerializeOptions): void {\n const combinedOptions = { ...this.defaultOptions, ...options }\n this.#new.push([name, value, combinedOptions])\n }\n\n delete(name: string, options?: Omit<SerializeOptions, 'expires' | 'maxAge'>): void {\n this.set(name, '', { ...options, expires: new Date(0), maxAge: 0 })\n }\n\n toHeaders(): Headers {\n const headers = new Headers()\n for (const [name, value, options] of this.#new)\n headers.append('Set-Cookie', serialize(name, value, options))\n\n return headers\n }\n}\n\nexport const CSRF_COOKIE_NAME = '__gau-csrf-token'\nexport const SESSION_COOKIE_NAME = '__gau-session-token'\nexport const SESSION_STRATEGY_COOKIE_NAME = '__gau-session-strategy'\nexport const LINKING_TOKEN_COOKIE_NAME = '__gau-linking-token'\nexport const PKCE_COOKIE_NAME = '__gau-pkce-code-verifier'\nexport const CALLBACK_URI_COOKIE_NAME = '__gau-callback-uri'\n\nexport const CSRF_MAX_AGE = 60 * 10 // 10 minutes\n","/// <reference types=\"node\" />\nimport {\n createJWTSignatureMessage,\n encodeJWT,\n JWSRegisteredHeaders,\n JWTRegisteredClaims,\n parseJWT,\n} from '@oslojs/jwt'\nimport { AuthError } from '../core/index'\nimport { constantTimeEqual, deriveKeysFromSecret, rawToDer } from './utils'\n\nexport type SupportedAlgorithm = 'ES256' | 'HS256'\n\ninterface CommonSignOptions {\n /** Time-to-live in seconds (exp claim). If omitted the token will not expire. */\n ttl?: number\n}\n\nexport type SignOptions\n = | ({ algorithm?: 'ES256', privateKey?: CryptoKey, secret?: string }\n & CommonSignOptions & { iss?: string, aud?: string | string[], sub?: string })\n | ({ algorithm: 'HS256', secret?: string | Uint8Array, privateKey?: never }\n & CommonSignOptions & { iss?: string, aud?: string | string[], sub?: string })\n\n/**\n * Create a signed JWT.\n * Defaults to ES256 when a privateKey is supplied. Falls back to HS256 when a secret is supplied.\n */\nexport async function sign<T extends Record<string, unknown>>(payload: T, options: SignOptions = {}): Promise<string> {\n let { algorithm = 'ES256', ttl, iss, aud, sub, privateKey, secret } = options\n\n if (algorithm === 'ES256') {\n if (!privateKey) {\n if (typeof secret !== 'string')\n throw new AuthError('Missing secret for ES256 signing. It must be a base64url-encoded string.');\n\n ({ privateKey } = await deriveKeysFromSecret(secret))\n }\n }\n else if (algorithm === 'HS256' && !secret) {\n throw new AuthError('Missing secret for HS256 signing')\n }\n\n const now = Math.floor(Date.now() / 1000)\n\n const jwtPayload: Record<string, unknown> = { iat: now, iss, aud, sub, ...payload }\n\n if (ttl != null && ttl > 0)\n jwtPayload.exp = now + ttl\n\n const isHS256 = algorithm === 'HS256'\n const alg: SupportedAlgorithm = isHS256 ? 'HS256' : 'ES256'\n\n const headerJSON = JSON.stringify({ alg, typ: 'JWT' })\n const payloadJSON = JSON.stringify(jwtPayload)\n\n const signatureMessage = createJWTSignatureMessage(headerJSON, payloadJSON)\n\n let signature: Uint8Array\n\n if (isHS256) {\n // HS256 (HMAC-SHA256)\n const secretBytes = typeof secret === 'string'\n ? new TextEncoder().encode(secret)\n : secret\n\n const cryptoKey = await crypto.subtle.importKey(\n 'raw',\n secretBytes as BufferSource,\n { name: 'HMAC', hash: 'SHA-256' },\n false,\n ['sign'],\n )\n\n signature = new Uint8Array(await crypto.subtle.sign('HMAC', cryptoKey, signatureMessage as BufferSource))\n }\n else {\n // ES256 (ECDSA-SHA256)\n // Runtimes like Bun's return the raw (r||s) signature directly, not DER-encoded.\n signature = new Uint8Array(\n await crypto.subtle.sign(\n { name: 'ECDSA', hash: 'SHA-256' },\n privateKey!,\n signatureMessage as BufferSource,\n ),\n )\n }\n\n return encodeJWT(headerJSON, payloadJSON, signature)\n}\n\nexport type VerifyOptions\n = | { algorithm?: 'ES256', publicKey?: CryptoKey, secret?: string, iss?: string, aud?: string | string[] }\n | { algorithm: 'HS256', secret?: string | Uint8Array, publicKey?: never, iss?: string, aud?: string | string[] }\n\n/**\n * Verify a JWT and return its payload when the signature is valid.\n * The algorithm is inferred from options – ES256 by default.\n * Throws when verification fails or the token is expired.\n */\nexport async function verify<T = Record<string, unknown>>(token: string, options: VerifyOptions): Promise<T> {\n let { algorithm = 'ES256', publicKey, secret, iss, aud } = options\n\n if (algorithm === 'ES256') {\n if (!publicKey) {\n if (typeof secret !== 'string')\n throw new AuthError('Missing secret for ES256 verification. Must be a base64url-encoded string.');\n\n ({ publicKey } = await deriveKeysFromSecret(secret))\n }\n }\n\n if (algorithm === 'HS256' && !secret)\n throw new AuthError('Missing secret for HS256 verification')\n\n const [header, payload, signature, signatureMessage] = parseJWT(token)\n\n const headerParams = new JWSRegisteredHeaders(header)\n const headerAlg = headerParams.algorithm()\n\n let validSignature = false\n\n // HS256 verification path\n if (algorithm === 'HS256') {\n if (headerAlg !== 'HS256')\n throw new Error(`JWT algorithm is \"${headerAlg}\", but verifier was configured for \"HS256\"`)\n\n const secretBytes = typeof secret === 'string'\n ? new TextEncoder().encode(secret)\n : secret\n\n const cryptoKey = await crypto.subtle.importKey(\n 'raw',\n secretBytes as BufferSource,\n { name: 'HMAC', hash: 'SHA-256' },\n false,\n ['sign'],\n )\n\n const expectedSig = new Uint8Array(await crypto.subtle.sign('HMAC', cryptoKey, signatureMessage as BufferSource))\n validSignature = constantTimeEqual(expectedSig, new Uint8Array(signature))\n }\n // ES256 verification path (default)\n else {\n if (headerAlg !== 'ES256')\n throw new AuthError(`JWT algorithm is \"${headerAlg}\", but verifier was configured for \"ES256\"`)\n\n const signatureBytes = new Uint8Array(signature)\n\n // Runtimes like Node.js return DER-encoded signatures. Others (Bun) return raw (r||s).\n // We try DER first, as it's more common in Node environments.\n validSignature = await crypto.subtle.verify(\n { name: 'ECDSA', hash: 'SHA-256' },\n publicKey!,\n signatureBytes as BufferSource,\n signatureMessage as BufferSource,\n )\n\n if (!validSignature && signatureBytes.length === 64) {\n // If DER verification fails and the signature is 64 bytes, it might be a raw signature.\n // Convert it to DER and try again.\n try {\n const derSig = rawToDer(signatureBytes)\n validSignature = await crypto.subtle.verify(\n { name: 'ECDSA', hash: 'SHA-256' },\n publicKey!,\n derSig as BufferSource,\n signatureMessage as BufferSource,\n )\n }\n catch {\n // rawToDer can throw if the signature is not 64 bytes, but we already checked.\n // This catch is for other unexpected errors.\n validSignature = false\n }\n }\n }\n\n if (!validSignature)\n throw new AuthError('Invalid JWT signature')\n\n const claims = new JWTRegisteredClaims(payload)\n if (claims.hasExpiration() && !claims.verifyExpiration())\n throw new AuthError('JWT expired')\n if (claims.hasNotBefore() && !claims.verifyNotBefore())\n throw new AuthError('JWT not yet valid')\n if (iss && (payload as any).iss !== iss)\n throw new AuthError('Invalid JWT issuer')\n\n if (aud) {\n const expectedAudience = Array.isArray(aud) ? aud : [aud]\n const tokenAudience = (payload as any).aud\n ? (Array.isArray((payload as any).aud) ? (payload as any).aud : [(payload as any).aud])\n : []\n\n if (!expectedAudience.some(audValue => tokenAudience.includes(audValue)))\n throw new AuthError('Invalid JWT audience')\n }\n\n return payload as T\n}\n","import { generateCodeVerifier, generateState } from 'arctic'\n\nexport function createOAuthUris() {\n const state = generateState()\n const codeVerifier = generateCodeVerifier()\n\n return {\n state,\n codeVerifier,\n }\n}\n","export interface RequestLike {\n /** Absolute or relative URL */\n readonly url: string\n /** Upper-case HTTP method (e.g. `GET`) */\n readonly method: string\n /** All HTTP headers – mutable so adapters can append */\n readonly headers: Headers\n /** Lazily parse the body as JSON */\n json: <T = unknown>() => Promise<T>\n /** Raw text body */\n text: () => Promise<string>\n /** FormData helper (for `application/x-www-form-urlencoded` or `multipart/form-data`) */\n formData: () => Promise<FormData>\n}\n\nexport interface ResponseLike {\n readonly status: number\n readonly headers: Headers\n readonly body?: BodyInit | null\n json: <T = unknown>() => Promise<T>\n text: () => Promise<string>\n}\n\nexport interface User {\n id: string\n name?: string | null\n email?: string | null\n emailVerified?: boolean | null\n image?: string | null\n}\n\nexport interface Session {\n id: string\n sub: string\n [key: string]: unknown\n}\n\nexport interface GauSession<TProviders extends string = string> {\n user: User | null\n session: Session | null\n accounts?: Account[] | null\n providers?: TProviders[]\n}\n\nexport const NULL_SESSION = {\n user: null,\n session: null,\n accounts: null,\n} as const\n\nexport interface NewUser extends Omit<User, 'id' | 'accounts'> {\n id?: string\n}\n\nexport interface Account {\n userId: string\n provider: string\n providerAccountId: string\n type?: string // e.g. \"oauth\"\n accessToken?: string | null\n refreshToken?: string | null\n expiresAt?: number | null // epoch seconds\n idToken?: string | null\n scope?: string | null\n tokenType?: string | null\n sessionState?: string | null\n}\n\nexport interface NewAccount extends Account {}\n\nexport interface Adapter {\n getUser: (id: string) => Promise<User | null>\n getUserByEmail: (email: string) => Promise<User | null>\n getUserByAccount: (provider: string, providerAccountId: string) => Promise<User | null>\n getAccounts: (userId: string) => Promise<Account[]>\n getUserAndAccounts: (userId: string) => Promise<{ user: User, accounts: Account[] } | null>\n createUser: (data: NewUser) => Promise<User>\n linkAccount: (data: NewAccount) => Promise<void>\n unlinkAccount: (provider: string, providerAccountId: string) => Promise<void>\n updateUser: (data: Partial<User> & { id: string }) => Promise<User>\n deleteUser: (id: string) => Promise<void>\n}\n\nexport class AuthError extends Error {\n override readonly cause?: unknown\n constructor(message: string, cause?: unknown) {\n super(message)\n this.name = 'AuthError'\n this.cause = cause\n }\n}\n\nexport function json<T>(data: T, init: ResponseInit = {}): Response {\n const headers = new Headers(init.headers)\n if (!headers.has('Content-Type'))\n headers.set('Content-Type', 'application/json; charset=utf-8')\n return new Response(JSON.stringify(data), { ...init, headers })\n}\n\nexport function redirect(url: string, status: 302 | 303 = 302): Response {\n return new Response(null, {\n status,\n headers: {\n Location: url,\n },\n })\n}\n\nexport * from './cookies'\nexport * from './createAuth'\nexport * from './handler'\n","import { BROWSER } from 'esm-env'\nimport { getSessionToken } from '../../client/token'\n\nexport const isTauri = BROWSER && '__TAURI_INTERNALS__' in (globalThis as any)\n\nexport async function signInWithTauri(\n provider: string,\n baseUrl: string,\n scheme: string = 'gau',\n redirectOverride?: string,\n) {\n if (!isTauri)\n return\n\n const { platform } = await import('@tauri-apps/plugin-os')\n const { open } = await import('@tauri-apps/plugin-shell')\n\n const currentPlatform = platform() // platform is NO LONGER an async function\n let redirectTo: string\n\n if (redirectOverride)\n redirectTo = redirectOverride\n else if (currentPlatform === 'android' || currentPlatform === 'ios')\n redirectTo = new URL(baseUrl).origin\n else\n redirectTo = `${scheme}://oauth/callback`\n\n const authUrl = `${baseUrl}/${provider}?redirectTo=${encodeURIComponent(redirectTo)}`\n await open(authUrl)\n}\n\nexport async function setupTauriListener(\n handler: (url: string) => Promise<void>,\n): Promise<(() => void) | void> {\n if (!isTauri)\n return\n\n const { listen } = await import('@tauri-apps/api/event')\n try {\n const unlisten = await listen<string>('deep-link', async (event) => {\n await handler(event.payload)\n })\n return unlisten\n }\n catch (err) {\n console.error(err)\n }\n}\n\nexport function handleTauriDeepLink(url: string, baseUrl: string, scheme: string, onToken: (token: string) => void) {\n const parsed = new URL(url)\n if (parsed.protocol !== `${scheme}:` && parsed.origin !== new URL(baseUrl).origin)\n return\n\n const params = new URLSearchParams(parsed.hash.substring(1))\n const token = params.get('token')\n if (token)\n onToken(token)\n}\n\nexport async function linkAccountWithTauri(\n provider: string,\n baseUrl: string,\n scheme: string = 'gau',\n redirectOverride?: string,\n) {\n if (!isTauri)\n return\n\n const { platform } = await import('@tauri-apps/plugin-os')\n const { open } = await import('@tauri-apps/plugin-shell')\n\n const currentPlatform = platform()\n let redirectTo: string\n\n if (redirectOverride)\n redirectTo = redirectOverride\n else if (currentPlatform === 'android' || currentPlatform === 'ios')\n redirectTo = new URL(baseUrl).origin\n else\n redirectTo = `${scheme}://oauth/callback`\n\n const token = getSessionToken()\n if (!token) {\n console.error('No session token found, cannot link account.')\n return\n }\n\n const query = `?redirectTo=${encodeURIComponent(redirectTo)}&token=${encodeURIComponent(token)}`\n const linkUrl = `${baseUrl}/link/${provider}${query}`\n await open(linkUrl)\n}\n","import { BROWSER } from 'esm-env'\n\nexport function storeSessionToken(token: string) {\n if (!BROWSER)\n return\n try {\n localStorage.setItem('gau-token', token)\n document.cookie = `__gau-session-token=${token}; path=/; max-age=31536000; samesite=lax; secure`\n }\n catch {}\n}\n\nexport function getSessionToken(): string | null {\n if (!BROWSER)\n return null\n return localStorage.getItem('gau-token')\n}\n\nexport function clearSessionToken() {\n if (!BROWSER)\n return\n try {\n localStorage.removeItem('gau-token')\n document.cookie = `__gau-session-token=; path=/; max-age=0`\n }\n catch {}\n}\n"],"mappings":"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","names":["BROWSER","BROWSER","BROWSER","BROWSER"]}
|
|
1
|
+
{"version":3,"sources":["../../../../src/client/svelte/index.svelte.ts","../../../../src/core/cookies.ts","../../../../src/jwt/jwt.ts","../../../../src/oauth/utils.ts","../../../../src/core/index.ts","../../../../src/runtimes/tauri/index.ts","../../../../src/client/token.ts"],"sourcesContent":["import type { GauSession, ProviderIds } from '../../core'\nimport { BROWSER } from 'esm-env'\nimport { getContext, setContext } from 'svelte'\nimport { NULL_SESSION } from '../../core'\nimport { handleTauriDeepLink, isTauri, linkAccountWithTauri, setupTauriListener, signInWithTauri } from '../../runtimes/tauri'\nimport { clearSessionToken, getSessionToken, storeSessionToken } from '../token'\n\ninterface AuthContextValue<TAuth = unknown> {\n session: GauSession<ProviderIds<TAuth>>\n signIn: (provider: ProviderIds<TAuth>, options?: { redirectTo?: string }) => Promise<void>\n linkAccount: (provider: ProviderIds<TAuth>, options?: { redirectTo?: string }) => Promise<void>\n unlinkAccount: (provider: ProviderIds<TAuth>) => Promise<void>\n signOut: () => Promise<void>\n}\n\nconst AUTH_CONTEXT_KEY = Symbol('gau-auth')\n\nexport function createSvelteAuth<const TAuth = unknown>({\n baseUrl = '/api/auth',\n scheme = 'gau',\n redirectTo: defaultRedirectTo,\n}: {\n baseUrl?: string\n scheme?: string\n redirectTo?: string\n} = {}) {\n type CurrentSession = GauSession<ProviderIds<TAuth>>\n let session = $state<CurrentSession>({ ...NULL_SESSION, providers: [] })\n\n async function fetchSession() {\n if (!BROWSER) {\n session = { ...NULL_SESSION, providers: [] }\n return\n }\n\n const token = getSessionToken()\n const headers = token ? { Authorization: `Bearer ${token}` } : undefined\n const res = await fetch(`${baseUrl}/session`, token ? { headers } : { credentials: 'include' })\n\n const contentType = res.headers.get('content-type')\n if (contentType?.includes('application/json')) {\n session = await res.json()\n }\n else {\n session = {\n ...NULL_SESSION,\n providers: [] as ProviderIds<TAuth>[],\n }\n }\n }\n\n async function signIn(provider: ProviderIds<TAuth>, { redirectTo }: { redirectTo?: string } = {}) {\n let finalRedirectTo = redirectTo ?? defaultRedirectTo\n if (isTauri) {\n await signInWithTauri(provider as string, baseUrl, scheme, finalRedirectTo)\n }\n else {\n if (!finalRedirectTo && BROWSER)\n finalRedirectTo = window.location.origin\n\n const query = finalRedirectTo ? `?redirectTo=${encodeURIComponent(finalRedirectTo)}` : ''\n window.location.href = `${baseUrl}/${provider as string}${query}`\n }\n }\n\n async function linkAccount(provider: ProviderIds<TAuth>, { redirectTo }: { redirectTo?: string } = {}) {\n if (isTauri) {\n await linkAccountWithTauri(provider as string, baseUrl, scheme, redirectTo)\n return\n }\n\n let finalRedirectTo = redirectTo ?? defaultRedirectTo\n if (!finalRedirectTo && BROWSER)\n finalRedirectTo = window.location.href\n\n const query = finalRedirectTo ? `?redirectTo=${encodeURIComponent(finalRedirectTo)}` : ''\n const linkUrl = `${baseUrl}/link/${provider as string}${query}${query ? '&' : '?'}redirect=false`\n\n const token = getSessionToken()\n\n const fetchOptions: RequestInit = token\n ? { headers: { Authorization: `Bearer ${token}` } }\n : { credentials: 'include' }\n\n const res = await fetch(linkUrl, fetchOptions)\n if (res.redirected) {\n window.location.href = res.url\n }\n else {\n try {\n const data = await res.json()\n if (data.url)\n window.location.href = data.url\n }\n catch (e) {\n console.error('Failed to parse response from link endpoint', e)\n }\n }\n }\n\n async function unlinkAccount(provider: ProviderIds<TAuth>) {\n const token = getSessionToken()\n const fetchOptions: RequestInit = token\n ? { headers: { Authorization: `Bearer ${token}` } }\n : { credentials: 'include' }\n\n const res = await fetch(`${baseUrl}/unlink/${provider as string}`, {\n method: 'POST',\n ...fetchOptions,\n })\n\n if (res.ok)\n await fetchSession()\n else\n console.error('Failed to unlink account', await res.json())\n }\n\n async function signOut() {\n clearSessionToken()\n const token = getSessionToken()\n const headers = token ? { Authorization: `Bearer ${token}` } : undefined\n await fetch(`${baseUrl}/signout`, token ? { method: 'POST', headers } : { method: 'POST', credentials: 'include' })\n await fetchSession()\n }\n\n if (BROWSER) {\n const hash = new URL(window.location.href).hash.substring(1)\n const params = new URLSearchParams(hash)\n const tokenFromUrl = params.get('token')\n\n if (tokenFromUrl) {\n storeSessionToken(tokenFromUrl)\n void (async () => {\n try {\n // @ts-expect-error - SvelteKit-only\n const { replaceState } = await import('$app/navigation')\n await replaceState(window.location.pathname + window.location.search, {})\n }\n catch {\n window.history.replaceState(null, '', window.location.pathname + window.location.search)\n }\n await fetchSession()\n })()\n }\n else {\n fetchSession()\n }\n }\n\n $effect(() => {\n if (!BROWSER || !isTauri)\n return\n\n let cleanup: (() => void) | void\n let disposed = false\n\n setupTauriListener(async (url) => {\n handleTauriDeepLink(url, baseUrl, scheme, async (token) => {\n storeSessionToken(token)\n await fetchSession()\n })\n }).then((unlisten) => {\n if (disposed)\n unlisten?.()\n else\n cleanup = unlisten\n })\n\n return () => {\n disposed = true\n cleanup?.()\n }\n })\n\n const contextValue: AuthContextValue<TAuth> = {\n get session() {\n return session\n },\n signIn: signIn as (provider: ProviderIds<TAuth>, options?: { redirectTo?: string }) => Promise<void>,\n linkAccount: linkAccount as (provider: ProviderIds<TAuth>, options?: { redirectTo?: string }) => Promise<void>,\n unlinkAccount: unlinkAccount as (provider: ProviderIds<TAuth>) => Promise<void>,\n signOut,\n }\n\n setContext(AUTH_CONTEXT_KEY, contextValue)\n}\n\nexport function useAuth<const TAuth = unknown>(): AuthContextValue<TAuth> {\n const context = getContext<AuthContextValue<TAuth>>(AUTH_CONTEXT_KEY)\n if (!context)\n throw new Error('useAuth must be used within an AuthProvider')\n\n return context\n}\n","import type { SerializeOptions } from 'cookie'\nimport { parse, serialize } from 'cookie'\n\nexport const DEFAULT_COOKIE_SERIALIZE_OPTIONS: SerializeOptions = {\n path: '/',\n sameSite: 'lax',\n secure: true,\n httpOnly: true,\n}\n\nexport type Cookie = [string, string, SerializeOptions]\n\nexport function parseCookies(cookieHeader: string | null | undefined): Map<string, string> {\n const cookies = new Map<string, string>()\n if (cookieHeader) {\n const parsed = parse(cookieHeader)\n for (const name in parsed)\n cookies.set(name, parsed[name]!)\n }\n return cookies\n}\n\nexport class Cookies {\n #new: Cookie[] = []\n\n constructor(\n private readonly requestCookies: Map<string, string>,\n private readonly defaultOptions: SerializeOptions,\n ) {}\n\n get(name: string): string | undefined {\n return this.requestCookies.get(name)\n }\n\n set(name: string, value: string, options?: SerializeOptions): void {\n const combinedOptions = { ...this.defaultOptions, ...options }\n this.#new.push([name, value, combinedOptions])\n }\n\n delete(name: string, options?: Omit<SerializeOptions, 'expires' | 'maxAge'>): void {\n this.set(name, '', { ...options, expires: new Date(0), maxAge: 0 })\n }\n\n toHeaders(): Headers {\n const headers = new Headers()\n for (const [name, value, options] of this.#new)\n headers.append('Set-Cookie', serialize(name, value, options))\n\n return headers\n }\n}\n\nexport const CSRF_COOKIE_NAME = '__gau-csrf-token'\nexport const SESSION_COOKIE_NAME = '__gau-session-token'\nexport const SESSION_STRATEGY_COOKIE_NAME = '__gau-session-strategy'\nexport const LINKING_TOKEN_COOKIE_NAME = '__gau-linking-token'\nexport const PKCE_COOKIE_NAME = '__gau-pkce-code-verifier'\nexport const CALLBACK_URI_COOKIE_NAME = '__gau-callback-uri'\n\nexport const CSRF_MAX_AGE = 60 * 10 // 10 minutes\n","/// <reference types=\"node\" />\nimport {\n createJWTSignatureMessage,\n encodeJWT,\n JWSRegisteredHeaders,\n JWTRegisteredClaims,\n parseJWT,\n} from '@oslojs/jwt'\nimport { AuthError } from '../core/index'\nimport { constantTimeEqual, deriveKeysFromSecret, rawToDer } from './utils'\n\nexport type SupportedAlgorithm = 'ES256' | 'HS256'\n\ninterface CommonSignOptions {\n /** Time-to-live in seconds (exp claim). If omitted the token will not expire. */\n ttl?: number\n}\n\nexport type SignOptions\n = | ({ algorithm?: 'ES256', privateKey?: CryptoKey, secret?: string }\n & CommonSignOptions & { iss?: string, aud?: string | string[], sub?: string })\n | ({ algorithm: 'HS256', secret?: string | Uint8Array, privateKey?: never }\n & CommonSignOptions & { iss?: string, aud?: string | string[], sub?: string })\n\n/**\n * Create a signed JWT.\n * Defaults to ES256 when a privateKey is supplied. Falls back to HS256 when a secret is supplied.\n */\nexport async function sign<T extends Record<string, unknown>>(payload: T, options: SignOptions = {}): Promise<string> {\n let { algorithm = 'ES256', ttl, iss, aud, sub, privateKey, secret } = options\n\n if (algorithm === 'ES256') {\n if (!privateKey) {\n if (typeof secret !== 'string')\n throw new AuthError('Missing secret for ES256 signing. It must be a base64url-encoded string.');\n\n ({ privateKey } = await deriveKeysFromSecret(secret))\n }\n }\n else if (algorithm === 'HS256' && !secret) {\n throw new AuthError('Missing secret for HS256 signing')\n }\n\n const now = Math.floor(Date.now() / 1000)\n\n const jwtPayload: Record<string, unknown> = { iat: now, iss, aud, sub, ...payload }\n\n if (ttl != null && ttl > 0)\n jwtPayload.exp = now + ttl\n\n const isHS256 = algorithm === 'HS256'\n const alg: SupportedAlgorithm = isHS256 ? 'HS256' : 'ES256'\n\n const headerJSON = JSON.stringify({ alg, typ: 'JWT' })\n const payloadJSON = JSON.stringify(jwtPayload)\n\n const signatureMessage = createJWTSignatureMessage(headerJSON, payloadJSON)\n\n let signature: Uint8Array\n\n if (isHS256) {\n // HS256 (HMAC-SHA256)\n const secretBytes = typeof secret === 'string'\n ? new TextEncoder().encode(secret)\n : secret\n\n const cryptoKey = await crypto.subtle.importKey(\n 'raw',\n secretBytes as BufferSource,\n { name: 'HMAC', hash: 'SHA-256' },\n false,\n ['sign'],\n )\n\n signature = new Uint8Array(await crypto.subtle.sign('HMAC', cryptoKey, signatureMessage as BufferSource))\n }\n else {\n // ES256 (ECDSA-SHA256)\n // Runtimes like Bun's return the raw (r||s) signature directly, not DER-encoded.\n signature = new Uint8Array(\n await crypto.subtle.sign(\n { name: 'ECDSA', hash: 'SHA-256' },\n privateKey!,\n signatureMessage as BufferSource,\n ),\n )\n }\n\n return encodeJWT(headerJSON, payloadJSON, signature)\n}\n\nexport type VerifyOptions\n = | { algorithm?: 'ES256', publicKey?: CryptoKey, secret?: string, iss?: string, aud?: string | string[] }\n | { algorithm: 'HS256', secret?: string | Uint8Array, publicKey?: never, iss?: string, aud?: string | string[] }\n\n/**\n * Verify a JWT and return its payload when the signature is valid.\n * The algorithm is inferred from options – ES256 by default.\n * Throws when verification fails or the token is expired.\n */\nexport async function verify<T = Record<string, unknown>>(token: string, options: VerifyOptions): Promise<T> {\n let { algorithm = 'ES256', publicKey, secret, iss, aud } = options\n\n if (algorithm === 'ES256') {\n if (!publicKey) {\n if (typeof secret !== 'string')\n throw new AuthError('Missing secret for ES256 verification. Must be a base64url-encoded string.');\n\n ({ publicKey } = await deriveKeysFromSecret(secret))\n }\n }\n\n if (algorithm === 'HS256' && !secret)\n throw new AuthError('Missing secret for HS256 verification')\n\n const [header, payload, signature, signatureMessage] = parseJWT(token)\n\n const headerParams = new JWSRegisteredHeaders(header)\n const headerAlg = headerParams.algorithm()\n\n let validSignature = false\n\n // HS256 verification path\n if (algorithm === 'HS256') {\n if (headerAlg !== 'HS256')\n throw new Error(`JWT algorithm is \"${headerAlg}\", but verifier was configured for \"HS256\"`)\n\n const secretBytes = typeof secret === 'string'\n ? new TextEncoder().encode(secret)\n : secret\n\n const cryptoKey = await crypto.subtle.importKey(\n 'raw',\n secretBytes as BufferSource,\n { name: 'HMAC', hash: 'SHA-256' },\n false,\n ['sign'],\n )\n\n const expectedSig = new Uint8Array(await crypto.subtle.sign('HMAC', cryptoKey, signatureMessage as BufferSource))\n validSignature = constantTimeEqual(expectedSig, new Uint8Array(signature))\n }\n // ES256 verification path (default)\n else {\n if (headerAlg !== 'ES256')\n throw new AuthError(`JWT algorithm is \"${headerAlg}\", but verifier was configured for \"ES256\"`)\n\n const signatureBytes = new Uint8Array(signature)\n\n // Runtimes like Node.js return DER-encoded signatures. Others (Bun) return raw (r||s).\n // We try DER first, as it's more common in Node environments.\n validSignature = await crypto.subtle.verify(\n { name: 'ECDSA', hash: 'SHA-256' },\n publicKey!,\n signatureBytes as BufferSource,\n signatureMessage as BufferSource,\n )\n\n if (!validSignature && signatureBytes.length === 64) {\n // If DER verification fails and the signature is 64 bytes, it might be a raw signature.\n // Convert it to DER and try again.\n try {\n const derSig = rawToDer(signatureBytes)\n validSignature = await crypto.subtle.verify(\n { name: 'ECDSA', hash: 'SHA-256' },\n publicKey!,\n derSig as BufferSource,\n signatureMessage as BufferSource,\n )\n }\n catch {\n // rawToDer can throw if the signature is not 64 bytes, but we already checked.\n // This catch is for other unexpected errors.\n validSignature = false\n }\n }\n }\n\n if (!validSignature)\n throw new AuthError('Invalid JWT signature')\n\n const claims = new JWTRegisteredClaims(payload)\n if (claims.hasExpiration() && !claims.verifyExpiration())\n throw new AuthError('JWT expired')\n if (claims.hasNotBefore() && !claims.verifyNotBefore())\n throw new AuthError('JWT not yet valid')\n if (iss && (payload as any).iss !== iss)\n throw new AuthError('Invalid JWT issuer')\n\n if (aud) {\n const expectedAudience = Array.isArray(aud) ? aud : [aud]\n const tokenAudience = (payload as any).aud\n ? (Array.isArray((payload as any).aud) ? (payload as any).aud : [(payload as any).aud])\n : []\n\n if (!expectedAudience.some(audValue => tokenAudience.includes(audValue)))\n throw new AuthError('Invalid JWT audience')\n }\n\n return payload as T\n}\n","import { generateCodeVerifier, generateState } from 'arctic'\n\nexport function createOAuthUris() {\n const state = generateState()\n const codeVerifier = generateCodeVerifier()\n\n return {\n state,\n codeVerifier,\n }\n}\n","export interface RequestLike {\n /** Absolute or relative URL */\n readonly url: string\n /** Upper-case HTTP method (e.g. `GET`) */\n readonly method: string\n /** All HTTP headers – mutable so adapters can append */\n readonly headers: Headers\n /** Lazily parse the body as JSON */\n json: <T = unknown>() => Promise<T>\n /** Raw text body */\n text: () => Promise<string>\n /** FormData helper (for `application/x-www-form-urlencoded` or `multipart/form-data`) */\n formData: () => Promise<FormData>\n}\n\nexport interface ResponseLike {\n readonly status: number\n readonly headers: Headers\n readonly body?: BodyInit | null\n json: <T = unknown>() => Promise<T>\n text: () => Promise<string>\n}\n\nexport interface User {\n id: string\n name?: string | null\n email?: string | null\n emailVerified?: boolean | null\n image?: string | null\n role?: string | null\n}\n\nexport interface Session {\n id: string\n sub: string\n [key: string]: unknown\n}\n\nexport interface GauSession<TProviders extends string = string> {\n user: User | null\n session: Session | null\n accounts?: Account[] | null\n providers?: TProviders[]\n}\n\nexport const NULL_SESSION = {\n user: null,\n session: null,\n accounts: null,\n} as const\n\nexport interface NewUser extends Omit<User, 'id' | 'accounts'> {\n id?: string\n}\n\nexport interface Account {\n userId: string\n provider: string\n providerAccountId: string\n type?: string // e.g. \"oauth\"\n accessToken?: string | null\n refreshToken?: string | null\n expiresAt?: number | null // epoch seconds\n idToken?: string | null\n scope?: string | null\n tokenType?: string | null\n sessionState?: string | null\n}\n\nexport interface NewAccount extends Account {}\n\nexport interface Adapter {\n getUser: (id: string) => Promise<User | null>\n getUserByEmail: (email: string) => Promise<User | null>\n getUserByAccount: (provider: string, providerAccountId: string) => Promise<User | null>\n getAccounts: (userId: string) => Promise<Account[]>\n getUserAndAccounts: (userId: string) => Promise<{ user: User, accounts: Account[] } | null>\n createUser: (data: NewUser) => Promise<User>\n linkAccount: (data: NewAccount) => Promise<void>\n unlinkAccount: (provider: string, providerAccountId: string) => Promise<void>\n updateUser: (data: Partial<User> & { id: string }) => Promise<User>\n deleteUser: (id: string) => Promise<void>\n}\n\nexport class AuthError extends Error {\n override readonly cause?: unknown\n constructor(message: string, cause?: unknown) {\n super(message)\n this.name = 'AuthError'\n this.cause = cause\n }\n}\n\nexport function json<T>(data: T, init: ResponseInit = {}): Response {\n const headers = new Headers(init.headers)\n if (!headers.has('Content-Type'))\n headers.set('Content-Type', 'application/json; charset=utf-8')\n return new Response(JSON.stringify(data), { ...init, headers })\n}\n\nexport function redirect(url: string, status: 302 | 303 = 302): Response {\n return new Response(null, {\n status,\n headers: {\n Location: url,\n },\n })\n}\n\nexport * from './cookies'\nexport * from './createAuth'\nexport * from './handler'\n","import { BROWSER } from 'esm-env'\nimport { getSessionToken } from '../../client/token'\n\nexport const isTauri = BROWSER && '__TAURI_INTERNALS__' in (globalThis as any)\n\nexport async function signInWithTauri(\n provider: string,\n baseUrl: string,\n scheme: string = 'gau',\n redirectOverride?: string,\n) {\n if (!isTauri)\n return\n\n const { platform } = await import('@tauri-apps/plugin-os')\n const { open } = await import('@tauri-apps/plugin-shell')\n\n const currentPlatform = platform() // platform is NO LONGER an async function\n let redirectTo: string\n\n if (redirectOverride)\n redirectTo = redirectOverride\n else if (currentPlatform === 'android' || currentPlatform === 'ios')\n redirectTo = new URL(baseUrl).origin\n else\n redirectTo = `${scheme}://oauth/callback`\n\n const authUrl = `${baseUrl}/${provider}?redirectTo=${encodeURIComponent(redirectTo)}`\n await open(authUrl)\n}\n\nexport async function setupTauriListener(\n handler: (url: string) => Promise<void>,\n): Promise<(() => void) | void> {\n if (!isTauri)\n return\n\n const { listen } = await import('@tauri-apps/api/event')\n try {\n const unlisten = await listen<string>('deep-link', async (event) => {\n await handler(event.payload)\n })\n return unlisten\n }\n catch (err) {\n console.error(err)\n }\n}\n\nexport function handleTauriDeepLink(url: string, baseUrl: string, scheme: string, onToken: (token: string) => void) {\n const parsed = new URL(url)\n if (parsed.protocol !== `${scheme}:` && parsed.origin !== new URL(baseUrl).origin)\n return\n\n const params = new URLSearchParams(parsed.hash.substring(1))\n const token = params.get('token')\n if (token)\n onToken(token)\n}\n\nexport async function linkAccountWithTauri(\n provider: string,\n baseUrl: string,\n scheme: string = 'gau',\n redirectOverride?: string,\n) {\n if (!isTauri)\n return\n\n const { platform } = await import('@tauri-apps/plugin-os')\n const { open } = await import('@tauri-apps/plugin-shell')\n\n const currentPlatform = platform()\n let redirectTo: string\n\n if (redirectOverride)\n redirectTo = redirectOverride\n else if (currentPlatform === 'android' || currentPlatform === 'ios')\n redirectTo = new URL(baseUrl).origin\n else\n redirectTo = `${scheme}://oauth/callback`\n\n const token = getSessionToken()\n if (!token) {\n console.error('No session token found, cannot link account.')\n return\n }\n\n const query = `?redirectTo=${encodeURIComponent(redirectTo)}&token=${encodeURIComponent(token)}`\n const linkUrl = `${baseUrl}/link/${provider}${query}`\n await open(linkUrl)\n}\n","import { BROWSER } from 'esm-env'\n\nexport function storeSessionToken(token: string) {\n if (!BROWSER)\n return\n try {\n localStorage.setItem('gau-token', token)\n document.cookie = `__gau-session-token=${token}; path=/; max-age=31536000; samesite=lax; secure`\n }\n catch {}\n}\n\nexport function getSessionToken(): string | null {\n if (!BROWSER)\n return null\n return localStorage.getItem('gau-token')\n}\n\nexport function clearSessionToken() {\n if (!BROWSER)\n return\n try {\n localStorage.removeItem('gau-token')\n document.cookie = `__gau-session-token=; path=/; max-age=0`\n }\n catch {}\n}\n"],"mappings":"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","names":["BROWSER","BROWSER","BROWSER","BROWSER"]}
|
|
@@ -37,6 +37,21 @@ export interface CreateAuthOptions<TProviders extends OAuthProvider[]> {
|
|
|
37
37
|
trustHosts?: 'all' | string[];
|
|
38
38
|
/** Account linking behavior: 'verifiedEmail' (default), 'always', or false. */
|
|
39
39
|
autoLink?: 'verifiedEmail' | 'always' | false;
|
|
40
|
+
/** Optional configuration for role-based access control. */
|
|
41
|
+
roles?: {
|
|
42
|
+
/** Default role for newly created users. */
|
|
43
|
+
defaultRole?: string;
|
|
44
|
+
/** Dynamically resolve the role at the moment of user creation. Return undefined to fall back to defaultRole. */
|
|
45
|
+
resolveOnCreate?: (context: {
|
|
46
|
+
providerId: string;
|
|
47
|
+
profile: any;
|
|
48
|
+
request: Request;
|
|
49
|
+
}) => string | undefined;
|
|
50
|
+
/** Roles that are considered admin-like for helper predicates. */
|
|
51
|
+
adminRoles?: string[];
|
|
52
|
+
/** Users that are always treated as admin for helper predicates. */
|
|
53
|
+
adminUserIds?: string[];
|
|
54
|
+
};
|
|
40
55
|
}
|
|
41
56
|
export type Auth<TProviders extends OAuthProvider[] = any> = Adapter & {
|
|
42
57
|
providerMap: Map<ProviderId<TProviders[number]>, TProviders[number]>;
|
|
@@ -53,7 +68,17 @@ export type Auth<TProviders extends OAuthProvider[] = any> = Adapter & {
|
|
|
53
68
|
autoLink: 'verifiedEmail' | 'always' | false;
|
|
54
69
|
sessionStrategy: 'auto' | 'cookie' | 'token';
|
|
55
70
|
development: boolean;
|
|
71
|
+
roles: {
|
|
72
|
+
defaultRole: string;
|
|
73
|
+
resolveOnCreate?: (context: {
|
|
74
|
+
providerId: string;
|
|
75
|
+
profile: any;
|
|
76
|
+
request: Request;
|
|
77
|
+
}) => string | undefined;
|
|
78
|
+
adminRoles: string[];
|
|
79
|
+
adminUserIds: string[];
|
|
80
|
+
};
|
|
56
81
|
};
|
|
57
|
-
export declare function createAuth<const TProviders extends OAuthProvider[]>({ adapter, providers, basePath, jwt: jwtConfig, session: sessionConfig, cookies: cookieConfig, trustHosts, autoLink }: CreateAuthOptions<TProviders>): Auth<TProviders>;
|
|
82
|
+
export declare function createAuth<const TProviders extends OAuthProvider[]>({ adapter, providers, basePath, jwt: jwtConfig, session: sessionConfig, cookies: cookieConfig, trustHosts, autoLink, roles: rolesConfig }: CreateAuthOptions<TProviders>): Auth<TProviders>;
|
|
58
83
|
export {};
|
|
59
84
|
//# sourceMappingURL=createAuth.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createAuth.d.ts","sourceRoot":"","sources":["../../../src/core/createAuth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,QAAQ,CAAA;AAC9C,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAA;AACxD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAC7C,OAAO,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAKlD,KAAK,UAAU,CAAC,CAAC,IAAI,CAAC,SAAS,aAAa,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK,CAAA;AACjE,MAAM,MAAM,WAAW,CAAC,CAAC,IAAI,CAAC,SAAS;IAAE,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,SAAS,MAAM,EAAE,GAAG,CAAC,CAAA;CAAE,GAAG,CAAC,GAAG,MAAM,CAAA;AAErG,MAAM,WAAW,iBAAiB,CAAC,UAAU,SAAS,aAAa,EAAE;IACnE,kEAAkE;IAClE,OAAO,EAAE,OAAO,CAAA;IAChB,2CAA2C;IAC3C,SAAS,EAAE,UAAU,CAAA;IACrB,qEAAqE;IACrE,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,iCAAiC;IACjC,OAAO,CAAC,EAAE;QACR,4EAA4E;QAC5E,QAAQ,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAA;KACvC,CAAA;IACD,sDAAsD;IACtD,GAAG,CAAC,EAAE;QACJ,uDAAuD;QACvD,SAAS,CAAC,EAAE,OAAO,GAAG,OAAO,CAAA;QAC7B,2FAA2F;QAC3F,MAAM,CAAC,EAAE,MAAM,CAAA;QACf,mCAAmC;QACnC,GAAG,CAAC,EAAE,MAAM,CAAA;QACZ,qCAAqC;QACrC,GAAG,CAAC,EAAE,MAAM,CAAA;QACZ,oEAAoE;QACpE,GAAG,CAAC,EAAE,MAAM,CAAA;KACb,CAAA;IACD,0CAA0C;IAC1C,OAAO,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC,CAAA;IACnC,uFAAuF;IACvF,UAAU,CAAC,EAAE,KAAK,GAAG,MAAM,EAAE,CAAA;IAC7B,+EAA+E;IAC/E,QAAQ,CAAC,EAAE,eAAe,GAAG,QAAQ,GAAG,KAAK,CAAA;
|
|
1
|
+
{"version":3,"file":"createAuth.d.ts","sourceRoot":"","sources":["../../../src/core/createAuth.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"callback.d.ts","sourceRoot":"","sources":["../../../../src/core/handlers/callback.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAA;AACzC,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAQ,MAAM,UAAU,CAAA;AAY/D,wBAAsB,cAAc,CAAC,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,
|
|
1
|
+
{"version":3,"file":"callback.d.ts","sourceRoot":"","sources":["../../../../src/core/handlers/callback.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAA;AACzC,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAQ,MAAM,UAAU,CAAA;AAY/D,wBAAsB,cAAc,CAAC,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAgUhH"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{applyCors as o,handleCallback as r,handleLink as m,handlePreflight as p,handleSession as t,handleSignIn as
|
|
1
|
+
import{applyCors as o,handleCallback as r,handleLink as m,handlePreflight as p,handleSession as t,handleSignIn as G,handleSignOut as W,handleUnlink as c,verifyRequestOrigin as e}from"../../../chunk-WEGQGDWC.js";export{o as applyCors,r as handleCallback,m as handleLink,p as handlePreflight,t as handleSession,G as handleSignIn,W as handleSignOut,c as handleUnlink,e as verifyRequestOrigin};//# sourceMappingURL=index.js.map
|
package/dist/src/core/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/index.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,WAAW;IAC1B,+BAA+B;IAC/B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,0CAA0C;IAC1C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,0DAAwD;IACxD,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,oCAAoC;IACpC,IAAI,EAAE,CAAC,CAAC,GAAG,OAAO,OAAO,OAAO,CAAC,CAAC,CAAC,CAAA;IACnC,oBAAoB;IACpB,IAAI,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAA;IAC3B,yFAAyF;IACzF,QAAQ,EAAE,MAAM,OAAO,CAAC,QAAQ,CAAC,CAAA;CAClC;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,QAAQ,CAAC,IAAI,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAA;IAC/B,IAAI,EAAE,CAAC,CAAC,GAAG,OAAO,OAAO,OAAO,CAAC,CAAC,CAAC,CAAA;IACnC,IAAI,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAA;CAC5B;AAED,MAAM,WAAW,IAAI;IACnB,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,aAAa,CAAC,EAAE,OAAO,GAAG,IAAI,CAAA;IAC9B,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/index.ts"],"names":[],"mappings":"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"}
|
package/dist/src/core/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{AuthError as o,CALLBACK_URI_COOKIE_NAME as r,CSRF_COOKIE_NAME as m,CSRF_MAX_AGE as p,Cookies as t,DEFAULT_COOKIE_SERIALIZE_OPTIONS as
|
|
1
|
+
import{AuthError as o,CALLBACK_URI_COOKIE_NAME as r,CSRF_COOKIE_NAME as m,CSRF_MAX_AGE as p,Cookies as t,DEFAULT_COOKIE_SERIALIZE_OPTIONS as G,LINKING_TOKEN_COOKIE_NAME as W,NULL_SESSION as c,PKCE_COOKIE_NAME as e,SESSION_COOKIE_NAME as f,SESSION_STRATEGY_COOKIE_NAME as h,createAuth as i,createHandler as j,json as k,parseCookies as n,redirect as s}from"../../chunk-WEGQGDWC.js";export{o as AuthError,r as CALLBACK_URI_COOKIE_NAME,m as CSRF_COOKIE_NAME,p as CSRF_MAX_AGE,t as Cookies,G as DEFAULT_COOKIE_SERIALIZE_OPTIONS,W as LINKING_TOKEN_COOKIE_NAME,c as NULL_SESSION,e as PKCE_COOKIE_NAME,f as SESSION_COOKIE_NAME,h as SESSION_STRATEGY_COOKIE_NAME,i as createAuth,j as createHandler,k as json,n as parseCookies,s as redirect};//# sourceMappingURL=index.js.map
|
package/dist/src/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{AuthError as o,CALLBACK_URI_COOKIE_NAME as r,CSRF_COOKIE_NAME as m,CSRF_MAX_AGE as p,Cookies as t,DEFAULT_COOKIE_SERIALIZE_OPTIONS as
|
|
1
|
+
import{AuthError as o,CALLBACK_URI_COOKIE_NAME as r,CSRF_COOKIE_NAME as m,CSRF_MAX_AGE as p,Cookies as t,DEFAULT_COOKIE_SERIALIZE_OPTIONS as G,LINKING_TOKEN_COOKIE_NAME as W,NULL_SESSION as c,PKCE_COOKIE_NAME as e,SESSION_COOKIE_NAME as f,SESSION_STRATEGY_COOKIE_NAME as h,createAuth as i,createHandler as j,json as k,parseCookies as n,redirect as s}from"../chunk-WEGQGDWC.js";export{o as AuthError,r as CALLBACK_URI_COOKIE_NAME,m as CSRF_COOKIE_NAME,p as CSRF_MAX_AGE,t as Cookies,G as DEFAULT_COOKIE_SERIALIZE_OPTIONS,W as LINKING_TOKEN_COOKIE_NAME,c as NULL_SESSION,e as PKCE_COOKIE_NAME,f as SESSION_COOKIE_NAME,h as SESSION_STRATEGY_COOKIE_NAME,i as createAuth,j as createHandler,k as json,n as parseCookies,s as redirect};//# sourceMappingURL=index.js.map
|
package/dist/src/jwt/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{sign as o,verify as r}from"../../chunk-
|
|
1
|
+
import{sign as o,verify as r}from"../../chunk-WEGQGDWC.js";export{o as sign,r as verify};//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{NULL_SESSION as e,SESSION_COOKIE_NAME as r,createAuth as t,createHandler as n,parseCookies as o}from"../../chunk-
|
|
1
|
+
import{NULL_SESSION as e,SESSION_COOKIE_NAME as r,createAuth as t,createHandler as n,parseCookies as o}from"../../chunk-WEGQGDWC.js";import s from"process";function i(e){const r="providerMap"in e&&"signJWT"in e?e:t(e);r.development="development"===s.env.NODE_ENV;const o=n(r),i=e=>o(e.request);return{GET:i,POST:i,OPTIONS:i}}function a(t){return async function(n){let s=o(n.headers.get("Cookie")).get(r);if(!s){const e=n.headers.get("Authorization");e?.startsWith("Bearer ")&&(s=e.substring(7))}const i=Array.from(t.providerMap.keys());if(!s)return{...e,providers:i};try{const r=await t.validateSession(s);return r?{...r,providers:i}:{...e,providers:i}}catch{return{...e,providers:i}}}}function c(e,r){const n=a("providerMap"in r&&"signJWT"in r?r:t(r));return async r=>{const t=new URL(r.request.url);if("boolean"==typeof e?e:e.includes(t.pathname)){const e=await n(r.request);return void(r.locals.getSession=async()=>e)}r.locals.getSession=()=>n(r.request)}}export{i as SolidAuth,c as authMiddleware,a as createSolidStartGetSession};//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{NULL_SESSION as e,SESSION_COOKIE_NAME as r,createAuth as t,createHandler as s,parseCookies as n}from"../../chunk-
|
|
1
|
+
import{NULL_SESSION as e,SESSION_COOKIE_NAME as r,createAuth as t,createHandler as s,parseCookies as n}from"../../chunk-WEGQGDWC.js";function o(o){const i="providerMap"in o&&"signJWT"in o?o:t(o);(async()=>{try{i.development=(await import("$app/environment")).dev}catch{i.development=!1}})();const a=s(i),c=e=>a(e.request);return{GET:c,POST:c,OPTIONS:c,handle:async({event:t,resolve:s})=>(t.locals.getSession=async()=>{let s=n(t.request.headers.get("Cookie")).get(r);if(!s){const e=t.request.headers.get("Authorization");e?.startsWith("Bearer ")&&(s=e.substring(7))}const o=Array.from(i.providerMap.keys());if(!s)return{...e,providers:o};try{const r=await i.validateSession(s);return r?{...r,providers:o}:{...e,providers:o}}catch{return{...e,providers:o}}},s(t))}}export{o as SvelteKitAuth};//# sourceMappingURL=index.js.map
|
package/package.json
CHANGED
package/dist/chunk-BU67DYGK.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{createJWTSignatureMessage as e,encodeJWT as t,JWSRegisteredHeaders as r,JWTRegisteredClaims as n,parseJWT as s}from"@oslojs/jwt";import{parse as o,serialize as i}from"cookie";var a={path:"/",sameSite:"lax",secure:!0,httpOnly:!0};function c(e){const t=new Map;if(e){const r=o(e);for(const e in r)t.set(e,r[e])}return t}var l=class{constructor(e,t){this.requestCookies=e,this.defaultOptions=t}#e=[];get(e){return this.requestCookies.get(e)}set(e,t,r){const n={...this.defaultOptions,...r};this.#e.push([e,t,n])}delete(e,t){this.set(e,"",{...t,expires:new Date(0),maxAge:0})}toHeaders(){const e=new Headers;for(const[t,r,n]of this.#e)e.append("Set-Cookie",i(t,r,n));return e}},u="__gau-csrf-token",d="__gau-session-token",h="__gau-session-strategy",f="__gau-linking-token",g="__gau-pkce-code-verifier",p="__gau-callback-uri",w=600;function m({adapter:e,providers:t,basePath:r="/api/auth",jwt:n={},session:s={},cookies:o={},trustHosts:i=[],autoLink:c="verifiedEmail"}){const{algorithm:l="ES256",secret:u,iss:d,aud:h,ttl:f=86400}=n,g={...a,...o},p=s.strategy??"auto";if("ES256"===l&&void 0!==u&&"string"!=typeof u)throw new M("For ES256, the secret option must be a string.");const w=new Map(t.map(e=>[e.id,e]));async function m(e,t={}){return N(e,function(e={}){const t={ttl:e.ttl,iss:e.iss??d,aud:e.aud??h,sub:e.sub};if("HS256"===l)return{algorithm:l,secret:e.secret??u,...t};{if(void 0!==e.secret&&"string"!=typeof e.secret)throw new M("For ES256, the secret option must be a string.");const r=e.secret??u;return{algorithm:l,privateKey:e.privateKey,secret:r,...t}}}(t))}async function y(e,t={}){const r=function(e={}){const t={iss:e.iss??d,aud:e.aud??h};if("HS256"===l)return{algorithm:l,secret:e.secret??u,...t};{if(void 0!==e.secret&&"string"!=typeof e.secret)throw new M("For ES256, the secret option must be a string.");const r=e.secret??u;return{algorithm:l,publicKey:e.publicKey,secret:r,...t}}}(t);try{return await F(e,r)}catch{return null}}return{...e,providerMap:w,basePath:r,cookieOptions:g,jwt:{ttl:f},signJWT:m,verifyJWT:y,createSession:async function(e,t={},r=f){return m({sub:e,...t},{ttl:r})},validateSession:async function(t){const r=await y(t);if(!r)return null;const n=await e.getUserAndAccounts(r.sub);if(!n)return null;const{user:s,accounts:o}=n;return{user:s,session:{id:t,...r},accounts:o}},trustHosts:i,autoLink:c,sessionStrategy:p,development:!1}}async function y(e,t,r){const n=t.providerMap.get(r);if(!n)return R({error:"Provider not found"},{status:400});const s=new URL(e.url),o=s.searchParams.get("code"),i=s.searchParams.get("state");if(!o||!i)return R({error:"Missing code or state"},{status:400});const a=c(e.headers.get("Cookie")),h=new l(a,t.cookieOptions);let w,m="/";if(i.includes(".")){const[e,t]=i.split(".");w=e;try{m=atob(t??"")||"/"}catch{m="/"}}else w=i;const y=h.get(u);if(!y||y!==w)return R({error:"Invalid CSRF token"},{status:403});const v=h.get(g);if(!v)return R({error:"Missing PKCE code verifier"},{status:400});const S=h.get(p),A=h.get(f);A&&h.delete(f);const k=!!A;if(k){if(!await t.validateSession(A)){h.delete(u),h.delete(g),S&&h.delete(p);const e=L(m);return h.toHeaders().forEach((t,r)=>e.headers.append(r,t)),e}}const{user:b,tokens:E}=await n.validateCallback(o,v,S??void 0);let C=null;const U=await t.getUserByAccount(r,b.id);if(k){if(C=(await t.validateSession(A)).user,!C)return R({error:"User not found"},{status:404});if(U&&U.id!==C.id)return R({error:"Account already linked to another user"},{status:409})}else C=U;if(!C){const e=t.autoLink??"verifiedEmail";if(b.email&&("always"===e||"verifiedEmail"===e&&!0===b.emailVerified)){const e=await t.getUserByEmail(b.email);e&&(C=b.emailVerified&&!e.emailVerified?await t.updateUser({id:e.id,emailVerified:!0}):e)}if(!C)try{C=await t.createUser({name:b.name,email:b.email,image:b.avatar,emailVerified:b.emailVerified})}catch(e){return console.error("Failed to create user:",e),R({error:"Failed to create user"},{status:500})}}if(C&&b.email){const{email:e,emailVerified:r}=C,{email:n,emailVerified:s}=b,o={id:C.id};let i=!1;if(e?e!==n||!0!==s||r||(o.emailVerified=!0,i=!0):(o.email=n,o.emailVerified=s??!1,i=!0),i)try{C=await t.updateUser(o)}catch(e){console.error("Failed to update user after sign-in:",e)}}if(!U){let e,n,s;try{e=E.refreshToken()}catch{e=null}try{const e=E.accessTokenExpiresAt();e&&(n=Math.floor(e.getTime()/1e3))}catch{}try{s=E.idToken()}catch{s=null}try{await t.linkAccount({userId:C.id,provider:r,providerAccountId:b.id,accessToken:E.accessToken(),refreshToken:e,expiresAt:n,tokenType:E.tokenType?.()??null,scope:E.scopes()?.join(" ")??null,idToken:s})}catch(e){return console.error("Error linking account:",e),R({error:"Failed to link account"},{status:500})}}const T=await t.createSession(C.id),H=new URL(e.url),P=new URL(m,e.url),x="token"===t.sessionStrategy,O="cookie"===t.sessionStrategy,M="gau:"===P.protocol,I=H.host!==P.host;if(x||!O&&(M||I)){const e=new URL(P);e.hash=`token=${T}`;const t=`<!DOCTYPE html>\n<html lang="en">\n<head>\n <meta charset="utf-8" />\n <title>Authentication Complete</title>\n <style>\n body {\n font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";\n background-color: #09090b;\n color: #fafafa;\n display: flex;\n justify-content: center;\n align-items: center;\n height: 100vh;\n margin: 0;\n text-align: center;\n }\n .card {\n background-color: #18181b;\n border: 1px solid #27272a;\n border-radius: 0.75rem;\n padding: 2rem;\n max-width: 320px;\n }\n h1 {\n font-size: 1.25rem;\n font-weight: 600;\n margin: 0 0 0.5rem;\n }\n p {\n margin: 0;\n color: #a1a1aa;\n }\n </style>\n <script>\n window.onload = function() {\n const url = ${JSON.stringify(e.toString())};\n window.location.href = url;\n setTimeout(window.close, 500);\n };\n <\/script>\n</head>\n<body>\n <div class="card">\n <h1>Authentication Successful</h1>\n <p>You can now close this window.</p>\n </div>\n</body>\n</html>`;h.delete(u),h.delete(g),S&&h.delete(p);const r=new Response(t,{status:200,headers:{"Content-Type":"text/html; charset=utf-8"}});return h.toHeaders().forEach((e,t)=>{r.headers.append(t,e)}),r}h.set(d,T,{maxAge:t.jwt.ttl,sameSite:t.development?"lax":"none",secure:!t.development}),h.delete(u),h.delete(g),S&&h.delete(p);let N;if("false"===s.searchParams.get("redirect")){const e=await t.getAccounts(C.id);N=R({user:{...C,accounts:e}})}else N=L(m);return h.toHeaders().forEach((e,t)=>{N.headers.append(t,e)}),N}function v(e,t){const r=e.headers.get("Origin")||e.headers.get("origin");return r?(t.headers.set("Access-Control-Allow-Origin",r),t.headers.set("Vary","Origin"),t.headers.set("Access-Control-Allow-Credentials","true"),t.headers.set("Access-Control-Allow-Headers","Content-Type, Authorization, Cookie"),t.headers.set("Access-Control-Allow-Methods","GET, POST, OPTIONS"),t):t}function S(e){const t=e.headers.get("Origin")||e.headers.get("origin")||"*";return new Response(null,{status:204,headers:{"Access-Control-Allow-Origin":t,"Access-Control-Allow-Credentials":"true","Access-Control-Allow-Headers":"Content-Type, Authorization, Cookie","Access-Control-Allow-Methods":"GET, POST, OPTIONS"}})}import{generateCodeVerifier as A,generateState as k}from"arctic";function b(e,t,r){if("all"===t)return!0;const n=e.headers.get("origin");if(!n)return!1;let s;try{s=new URL(n).host}catch{return!1}if(r){if(s.startsWith("localhost")||s.startsWith("127.0.0.1"))return!0}const o=new URL(e.url),i=o.host;return n===`${o.protocol}//${i}`||t.includes(s)}async function E(e,t,r,n){const s=t.providerMap.get(r);if(!s)return R({error:"Provider not found"},{status:400});const{state:o,codeVerifier:i}={state:k(),codeVerifier:A()},a=new URL(e.url),d=a.searchParams.get("redirectTo");if(d){let r;try{if(d.startsWith("//"))throw new Error("Protocol-relative URL not allowed");r=new URL(d,a.origin)}catch{return R({error:'Invalid "redirectTo" URL'},{status:400})}const n=r.host,s=n===new URL(e.url).host,o="all"===t.trustHosts||t.trustHosts.includes(n);if(("http:"===r.protocol||"https:"===r.protocol)&&!s&&!o)return R({error:"Untrusted redirect host"},{status:400})}const h=d?`${o}.${btoa(d)}`:o;let w,m=a.searchParams.get("callbackUri");!m&&s.requiresRedirectUri&&(m=`${a.origin}${t.basePath}/${r}/callback`);try{w=await s.getAuthorizationUrl(h,i,{redirectUri:m??void 0})}catch(e){console.error("Error getting authorization URL:",e),w=null}if(!w)return R({error:"Could not create authorization URL"},{status:500});const y=c(e.headers.get("Cookie")),v=new l(y,t.cookieOptions),S={maxAge:600,sameSite:t.development?"lax":"none",secure:!t.development};v.set(u,o,S),v.set(g,i,S),n&&v.set(f,n,S),m&&v.set(p,m,S);if("false"===a.searchParams.get("redirect")){const e=R({url:w.toString()});return v.toHeaders().forEach((t,r)=>{e.headers.append(r,t)}),e}const b=L(w.toString());return v.toHeaders().forEach((e,t)=>{b.headers.append(t,e)}),b}async function C(e,t,r){const n=new URL(e.url);let s=c(e.headers.get("Cookie")).get(d);if(!s){const t=e.headers.get("Authorization");t?.startsWith("Bearer ")&&(s=t.substring(7))}if(s||(s=n.searchParams.get("token")??void 0),!s)return R({error:"Unauthorized"},{status:401});if(!await t.validateSession(s))return R({error:"Unauthorized"},{status:401});n.searchParams.delete("token");return E(new Request(n.toString(),e),t,r,s)}async function U(e,t,r){let n=c(e.headers.get("Cookie")).get(d);if(!n){const t=e.headers.get("Authorization");t?.startsWith("Bearer ")&&(n=t.substring(7))}if(!n)return R({error:"Unauthorized"},{status:401});const s=await t.validateSession(n);if(!s||!s.user)return R({error:"Unauthorized"},{status:401});const o=s.accounts??[];if(o.length<=1)return R({error:"Cannot unlink the last account"},{status:400});const i=o.find(e=>e.provider===r);if(!i)return R({error:`Provider "${r}" not linked to this account`},{status:400});await t.unlinkAccount(r,i.providerAccountId);if((await t.getAccounts(s.user.id)).length>0&&s.user.email)try{await t.updateUser({id:s.user.id,email:null,emailVerified:!1})}catch(e){console.error("Failed to clear stale email after unlinking:",e)}return R({message:"Account unlinked successfully"})}async function T(e,t,r){return E(e,t,r,null)}async function H(e,t){const r=c(e.headers.get("Cookie")),n=new l(r,t.cookieOptions);n.delete(d,{sameSite:t.development?"lax":"none",secure:!t.development});const s=R({message:"Signed out"});return n.toHeaders().forEach((e,t)=>{s.headers.append(t,e)}),s}async function P(e,t){let r=c(e.headers.get("Cookie")).get(d);if(!r){const t=e.headers.get("Authorization");t?.startsWith("Bearer ")&&(r=t.substring(7))}const n=Array.from(t.providerMap.keys());if(!r)return R({...O,providers:n});try{const e=await t.validateSession(r);return e?R({...e,providers:n}):R({...O,providers:n},{status:401})}catch(e){return console.error("Error validating session:",e),R({error:"Failed to validate session"},{status:500})}}function x(e){const{basePath:t}=e;return async function(r){if("OPTIONS"===r.method)return S(r);const n=new URL(r.url);if(!n.pathname.startsWith(t))return v(r,R({error:"Not Found"},{status:404}));if("POST"===r.method&&!b(r,e.trustHosts,e.development)){if(e.development){const e=r.headers.get("origin")??"N/A";return v(r,R({error:"Forbidden",message:`Untrusted origin: '${e}'. Add this origin to 'trustHosts' in createAuth() or ensure you are using 'localhost' or '127.0.0.1' for development.`},{status:403}))}return v(r,R({error:"Forbidden"},{status:403}))}const s=n.pathname.substring(t.length).split("/").filter(Boolean),o=s[0];if(!o)return v(r,R({error:"Not Found"},{status:404}));let i;return i="GET"===r.method?"session"===o?await P(r,e):2===s.length&&"link"===s[0]?await C(r,e,s[1]):2===s.length&&"callback"===s[1]?await y(r,e,o):1===s.length?await T(r,e,o):R({error:"Not Found"},{status:404}):"POST"===r.method?1===s.length&&"signout"===o?await H(r,e):2===s.length&&"unlink"===s[0]?await U(r,e,s[1]):R({error:"Not Found"},{status:404}):R({error:"Method Not Allowed"},{status:405}),v(r,i)}}var O={user:null,session:null,accounts:null},M=class extends Error{cause;constructor(e,t){super(e),this.name="AuthError",this.cause=t}};function R(e,t={}){const r=new Headers(t.headers);return r.has("Content-Type")||r.set("Content-Type","application/json; charset=utf-8"),new Response(JSON.stringify(e),{...t,headers:r})}function L(e,t=302){return new Response(null,{status:t,headers:{Location:e}})}async function I(e){try{const t=function(e){const t=e.replace(/-/g,"+").replace(/_/g,"/"),r=(4-t.length%4)%4,n=t.padEnd(t.length+r,"=");try{const e=atob(n),t=e.length,r=new Uint8Array(t);for(let n=0;n<t;n++)r[n]=e.charCodeAt(n);return r}catch{throw new M("Invalid base64url string")}}(e),r=await crypto.subtle.importKey("pkcs8",t.slice(),{name:"ECDSA",namedCurve:"P-256"},!0,["sign"]),n=await crypto.subtle.exportKey("jwk",r);delete n.d,n.key_ops=["verify"];return{privateKey:r,publicKey:await crypto.subtle.importKey("jwk",n,{name:"ECDSA",namedCurve:"P-256"},!0,["verify"])}}catch(e){if(e instanceof M)throw e;throw new M("Invalid secret. Must be a base64url-encoded PKCS#8 private key for ES256. Use `bunx gau secret` to generate one.",e)}}async function N(r,n={}){let{algorithm:s="ES256",ttl:o,iss:i,aud:a,sub:c,privateKey:l,secret:u}=n;if("ES256"===s){if(!l){if("string"!=typeof u)throw new M("Missing secret for ES256 signing. It must be a base64url-encoded string.");({privateKey:l}=await I(u))}}else if("HS256"===s&&!u)throw new M("Missing secret for HS256 signing");const d=Math.floor(Date.now()/1e3),h={iat:d,iss:i,aud:a,sub:c,...r};null!=o&&o>0&&(h.exp=d+o);const f="HS256"===s,g=f?"HS256":"ES256",p=JSON.stringify({alg:g,typ:"JWT"}),w=JSON.stringify(h),m=e(p,w);let y;if(f){const e="string"==typeof u?(new TextEncoder).encode(u):u,t=await crypto.subtle.importKey("raw",e,{name:"HMAC",hash:"SHA-256"},!1,["sign"]);y=new Uint8Array(await crypto.subtle.sign("HMAC",t,m))}else y=new Uint8Array(await crypto.subtle.sign({name:"ECDSA",hash:"SHA-256"},l,m));return t(p,w,y)}async function F(e,t){let{algorithm:o="ES256",publicKey:i,secret:a,iss:c,aud:l}=t;if("ES256"===o&&!i){if("string"!=typeof a)throw new M("Missing secret for ES256 verification. Must be a base64url-encoded string.");({publicKey:i}=await I(a))}if("HS256"===o&&!a)throw new M("Missing secret for HS256 verification");const[u,d,h,f]=s(e),g=new r(u).algorithm();let p=!1;if("HS256"===o){if("HS256"!==g)throw new Error(`JWT algorithm is "${g}", but verifier was configured for "HS256"`);const e="string"==typeof a?(new TextEncoder).encode(a):a,t=await crypto.subtle.importKey("raw",e,{name:"HMAC",hash:"SHA-256"},!1,["sign"]);p=function(e,t){let r=e.length^t.length;const n=Math.max(e.length,t.length);for(let s=0;s<n;s++)r|=(e[s]??0)^(t[s]??0);return 0===r}(new Uint8Array(await crypto.subtle.sign("HMAC",t,f)),new Uint8Array(h))}else{if("ES256"!==g)throw new M(`JWT algorithm is "${g}", but verifier was configured for "ES256"`);const e=new Uint8Array(h);if(p=await crypto.subtle.verify({name:"ECDSA",hash:"SHA-256"},i,e,f),!p&&64===e.length)try{const t=function(e){if(64!==e.length)throw new Error("Invalid raw signature length");let t=e.slice(0,32),r=e.slice(32),n=0;for(;n<t.length-1&&0===t[n];)n++;t=t.slice(n);let s=0;for(;s<r.length-1&&0===r[s];)s++;if(r=r.slice(s),t.length>0&&128&t[0]){const e=new Uint8Array(t.length+1);e[0]=0,e.set(t,1),t=e}if(r.length>0&&128&r[0]){const e=new Uint8Array(r.length+1);e[0]=0,e.set(r,1),r=e}const o=t.length,i=r.length,a=2+o+2+i,c=new Uint8Array(2+a);return c[0]=48,c[1]=a,c[2]=2,c[3]=o,c.set(t,4),c[4+o]=2,c[5+o]=i,c.set(r,6+o),c}(e);p=await crypto.subtle.verify({name:"ECDSA",hash:"SHA-256"},i,t,f)}catch{p=!1}}if(!p)throw new M("Invalid JWT signature");const w=new n(d);if(w.hasExpiration()&&!w.verifyExpiration())throw new M("JWT expired");if(w.hasNotBefore()&&!w.verifyNotBefore())throw new M("JWT not yet valid");if(c&&d.iss!==c)throw new M("Invalid JWT issuer");if(l){const e=Array.isArray(l)?l:[l],t=d.aud?Array.isArray(d.aud)?d.aud:[d.aud]:[];if(!e.some(e=>t.includes(e)))throw new M("Invalid JWT audience")}return d}export{a as DEFAULT_COOKIE_SERIALIZE_OPTIONS,c as parseCookies,l as Cookies,u as CSRF_COOKIE_NAME,d as SESSION_COOKIE_NAME,h as SESSION_STRATEGY_COOKIE_NAME,f as LINKING_TOKEN_COOKIE_NAME,g as PKCE_COOKIE_NAME,p as CALLBACK_URI_COOKIE_NAME,w as CSRF_MAX_AGE,N as sign,F as verify,m as createAuth,y as handleCallback,v as applyCors,S as handlePreflight,b as verifyRequestOrigin,C as handleLink,U as handleUnlink,T as handleSignIn,H as handleSignOut,P as handleSession,x as createHandler,O as NULL_SESSION,M as AuthError,R as json,L as redirect};//# sourceMappingURL=chunk-BU67DYGK.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/jwt/jwt.ts","../src/core/cookies.ts","../src/core/createAuth.ts","../src/core/handlers/callback.ts","../src/core/handlers/cors.ts","../src/oauth/utils.ts","../src/core/handlers/utils.ts","../src/core/handlers/link.ts","../src/core/handlers/login.ts","../src/core/handlers/session.ts","../src/core/handler.ts","../src/core/index.ts","../src/jwt/utils.ts"],"sourcesContent":["/// <reference types=\"node\" />\nimport {\n createJWTSignatureMessage,\n encodeJWT,\n JWSRegisteredHeaders,\n JWTRegisteredClaims,\n parseJWT,\n} from '@oslojs/jwt'\nimport { AuthError } from '../core/index'\nimport { constantTimeEqual, deriveKeysFromSecret, rawToDer } from './utils'\n\nexport type SupportedAlgorithm = 'ES256' | 'HS256'\n\ninterface CommonSignOptions {\n /** Time-to-live in seconds (exp claim). If omitted the token will not expire. */\n ttl?: number\n}\n\nexport type SignOptions\n = | ({ algorithm?: 'ES256', privateKey?: CryptoKey, secret?: string }\n & CommonSignOptions & { iss?: string, aud?: string | string[], sub?: string })\n | ({ algorithm: 'HS256', secret?: string | Uint8Array, privateKey?: never }\n & CommonSignOptions & { iss?: string, aud?: string | string[], sub?: string })\n\n/**\n * Create a signed JWT.\n * Defaults to ES256 when a privateKey is supplied. Falls back to HS256 when a secret is supplied.\n */\nexport async function sign<T extends Record<string, unknown>>(payload: T, options: SignOptions = {}): Promise<string> {\n let { algorithm = 'ES256', ttl, iss, aud, sub, privateKey, secret } = options\n\n if (algorithm === 'ES256') {\n if (!privateKey) {\n if (typeof secret !== 'string')\n throw new AuthError('Missing secret for ES256 signing. It must be a base64url-encoded string.');\n\n ({ privateKey } = await deriveKeysFromSecret(secret))\n }\n }\n else if (algorithm === 'HS256' && !secret) {\n throw new AuthError('Missing secret for HS256 signing')\n }\n\n const now = Math.floor(Date.now() / 1000)\n\n const jwtPayload: Record<string, unknown> = { iat: now, iss, aud, sub, ...payload }\n\n if (ttl != null && ttl > 0)\n jwtPayload.exp = now + ttl\n\n const isHS256 = algorithm === 'HS256'\n const alg: SupportedAlgorithm = isHS256 ? 'HS256' : 'ES256'\n\n const headerJSON = JSON.stringify({ alg, typ: 'JWT' })\n const payloadJSON = JSON.stringify(jwtPayload)\n\n const signatureMessage = createJWTSignatureMessage(headerJSON, payloadJSON)\n\n let signature: Uint8Array\n\n if (isHS256) {\n // HS256 (HMAC-SHA256)\n const secretBytes = typeof secret === 'string'\n ? new TextEncoder().encode(secret)\n : secret\n\n const cryptoKey = await crypto.subtle.importKey(\n 'raw',\n secretBytes as BufferSource,\n { name: 'HMAC', hash: 'SHA-256' },\n false,\n ['sign'],\n )\n\n signature = new Uint8Array(await crypto.subtle.sign('HMAC', cryptoKey, signatureMessage as BufferSource))\n }\n else {\n // ES256 (ECDSA-SHA256)\n // Runtimes like Bun's return the raw (r||s) signature directly, not DER-encoded.\n signature = new Uint8Array(\n await crypto.subtle.sign(\n { name: 'ECDSA', hash: 'SHA-256' },\n privateKey!,\n signatureMessage as BufferSource,\n ),\n )\n }\n\n return encodeJWT(headerJSON, payloadJSON, signature)\n}\n\nexport type VerifyOptions\n = | { algorithm?: 'ES256', publicKey?: CryptoKey, secret?: string, iss?: string, aud?: string | string[] }\n | { algorithm: 'HS256', secret?: string | Uint8Array, publicKey?: never, iss?: string, aud?: string | string[] }\n\n/**\n * Verify a JWT and return its payload when the signature is valid.\n * The algorithm is inferred from options – ES256 by default.\n * Throws when verification fails or the token is expired.\n */\nexport async function verify<T = Record<string, unknown>>(token: string, options: VerifyOptions): Promise<T> {\n let { algorithm = 'ES256', publicKey, secret, iss, aud } = options\n\n if (algorithm === 'ES256') {\n if (!publicKey) {\n if (typeof secret !== 'string')\n throw new AuthError('Missing secret for ES256 verification. Must be a base64url-encoded string.');\n\n ({ publicKey } = await deriveKeysFromSecret(secret))\n }\n }\n\n if (algorithm === 'HS256' && !secret)\n throw new AuthError('Missing secret for HS256 verification')\n\n const [header, payload, signature, signatureMessage] = parseJWT(token)\n\n const headerParams = new JWSRegisteredHeaders(header)\n const headerAlg = headerParams.algorithm()\n\n let validSignature = false\n\n // HS256 verification path\n if (algorithm === 'HS256') {\n if (headerAlg !== 'HS256')\n throw new Error(`JWT algorithm is \"${headerAlg}\", but verifier was configured for \"HS256\"`)\n\n const secretBytes = typeof secret === 'string'\n ? new TextEncoder().encode(secret)\n : secret\n\n const cryptoKey = await crypto.subtle.importKey(\n 'raw',\n secretBytes as BufferSource,\n { name: 'HMAC', hash: 'SHA-256' },\n false,\n ['sign'],\n )\n\n const expectedSig = new Uint8Array(await crypto.subtle.sign('HMAC', cryptoKey, signatureMessage as BufferSource))\n validSignature = constantTimeEqual(expectedSig, new Uint8Array(signature))\n }\n // ES256 verification path (default)\n else {\n if (headerAlg !== 'ES256')\n throw new AuthError(`JWT algorithm is \"${headerAlg}\", but verifier was configured for \"ES256\"`)\n\n const signatureBytes = new Uint8Array(signature)\n\n // Runtimes like Node.js return DER-encoded signatures. Others (Bun) return raw (r||s).\n // We try DER first, as it's more common in Node environments.\n validSignature = await crypto.subtle.verify(\n { name: 'ECDSA', hash: 'SHA-256' },\n publicKey!,\n signatureBytes as BufferSource,\n signatureMessage as BufferSource,\n )\n\n if (!validSignature && signatureBytes.length === 64) {\n // If DER verification fails and the signature is 64 bytes, it might be a raw signature.\n // Convert it to DER and try again.\n try {\n const derSig = rawToDer(signatureBytes)\n validSignature = await crypto.subtle.verify(\n { name: 'ECDSA', hash: 'SHA-256' },\n publicKey!,\n derSig as BufferSource,\n signatureMessage as BufferSource,\n )\n }\n catch {\n // rawToDer can throw if the signature is not 64 bytes, but we already checked.\n // This catch is for other unexpected errors.\n validSignature = false\n }\n }\n }\n\n if (!validSignature)\n throw new AuthError('Invalid JWT signature')\n\n const claims = new JWTRegisteredClaims(payload)\n if (claims.hasExpiration() && !claims.verifyExpiration())\n throw new AuthError('JWT expired')\n if (claims.hasNotBefore() && !claims.verifyNotBefore())\n throw new AuthError('JWT not yet valid')\n if (iss && (payload as any).iss !== iss)\n throw new AuthError('Invalid JWT issuer')\n\n if (aud) {\n const expectedAudience = Array.isArray(aud) ? aud : [aud]\n const tokenAudience = (payload as any).aud\n ? (Array.isArray((payload as any).aud) ? (payload as any).aud : [(payload as any).aud])\n : []\n\n if (!expectedAudience.some(audValue => tokenAudience.includes(audValue)))\n throw new AuthError('Invalid JWT audience')\n }\n\n return payload as T\n}\n","import type { SerializeOptions } from 'cookie'\nimport { parse, serialize } from 'cookie'\n\nexport const DEFAULT_COOKIE_SERIALIZE_OPTIONS: SerializeOptions = {\n path: '/',\n sameSite: 'lax',\n secure: true,\n httpOnly: true,\n}\n\nexport type Cookie = [string, string, SerializeOptions]\n\nexport function parseCookies(cookieHeader: string | null | undefined): Map<string, string> {\n const cookies = new Map<string, string>()\n if (cookieHeader) {\n const parsed = parse(cookieHeader)\n for (const name in parsed)\n cookies.set(name, parsed[name]!)\n }\n return cookies\n}\n\nexport class Cookies {\n #new: Cookie[] = []\n\n constructor(\n private readonly requestCookies: Map<string, string>,\n private readonly defaultOptions: SerializeOptions,\n ) {}\n\n get(name: string): string | undefined {\n return this.requestCookies.get(name)\n }\n\n set(name: string, value: string, options?: SerializeOptions): void {\n const combinedOptions = { ...this.defaultOptions, ...options }\n this.#new.push([name, value, combinedOptions])\n }\n\n delete(name: string, options?: Omit<SerializeOptions, 'expires' | 'maxAge'>): void {\n this.set(name, '', { ...options, expires: new Date(0), maxAge: 0 })\n }\n\n toHeaders(): Headers {\n const headers = new Headers()\n for (const [name, value, options] of this.#new)\n headers.append('Set-Cookie', serialize(name, value, options))\n\n return headers\n }\n}\n\nexport const CSRF_COOKIE_NAME = '__gau-csrf-token'\nexport const SESSION_COOKIE_NAME = '__gau-session-token'\nexport const SESSION_STRATEGY_COOKIE_NAME = '__gau-session-strategy'\nexport const LINKING_TOKEN_COOKIE_NAME = '__gau-linking-token'\nexport const PKCE_COOKIE_NAME = '__gau-pkce-code-verifier'\nexport const CALLBACK_URI_COOKIE_NAME = '__gau-callback-uri'\n\nexport const CSRF_MAX_AGE = 60 * 10 // 10 minutes\n","import type { SerializeOptions } from 'cookie'\nimport type { SignOptions, VerifyOptions } from '../jwt'\nimport type { OAuthProvider } from '../oauth'\nimport type { Adapter, GauSession } from './index'\nimport { sign, verify } from '../jwt'\nimport { DEFAULT_COOKIE_SERIALIZE_OPTIONS } from './cookies'\nimport { AuthError } from './index'\n\ntype ProviderId<P> = P extends OAuthProvider<infer T> ? T : never\nexport type ProviderIds<T> = T extends { providerMap: Map<infer K extends string, any> } ? K : string\n\nexport interface CreateAuthOptions<TProviders extends OAuthProvider[]> {\n /** The database adapter to use for storing users and accounts. */\n adapter: Adapter\n /** Array of OAuth providers to support. */\n providers: TProviders\n /** Base path for authentication routes (defaults to '/api/auth'). */\n basePath?: string\n /** Session management options */\n session?: {\n /** Strategy to use for sessions: 'auto' (default), 'cookie', or 'token'. */\n strategy?: 'auto' | 'cookie' | 'token'\n }\n /** Configuration for JWT signing and verification. */\n jwt?: {\n /** Signing algorithm: 'ES256' (default) or 'HS256'. */\n algorithm?: 'ES256' | 'HS256'\n /** Secret for HS256 or base64url-encoded private key for ES256 (overrides AUTH_SECRET). */\n secret?: string\n /** Issuer claim (iss) for JWTs. */\n iss?: string\n /** Audience claim (aud) for JWTs. */\n aud?: string\n /** Default time-to-live in seconds for JWTs (defaults to 1 day). */\n ttl?: number\n }\n /** Custom options for session cookies. */\n cookies?: Partial<SerializeOptions>\n /** Trusted hosts for CSRF protection: 'all' or array of hostnames (defaults to []). */\n trustHosts?: 'all' | string[]\n /** Account linking behavior: 'verifiedEmail' (default), 'always', or false. */\n autoLink?: 'verifiedEmail' | 'always' | false\n}\n\nexport type Auth<TProviders extends OAuthProvider[] = any> = Adapter & {\n providerMap: Map<ProviderId<TProviders[number]>, TProviders[number]>\n basePath: string\n cookieOptions: SerializeOptions\n jwt: {\n ttl: number\n }\n signJWT: <U extends Record<string, unknown>>(payload: U, customOptions?: Partial<SignOptions>) => Promise<string>\n verifyJWT: <U = Record<string, unknown>>(token: string, customOptions?: Partial<VerifyOptions>) => Promise<U | null>\n createSession: (userId: string, data?: Record<string, unknown>, ttl?: number) => Promise<string>\n validateSession: (token: string) => Promise<GauSession | null>\n trustHosts: 'all' | string[]\n autoLink: 'verifiedEmail' | 'always' | false\n sessionStrategy: 'auto' | 'cookie' | 'token'\n development: boolean\n}\n\nexport function createAuth<const TProviders extends OAuthProvider[]>({\n adapter,\n providers,\n basePath = '/api/auth',\n jwt: jwtConfig = {},\n session: sessionConfig = {},\n cookies: cookieConfig = {},\n trustHosts = [],\n autoLink = 'verifiedEmail',\n}: CreateAuthOptions<TProviders>): Auth<TProviders> {\n const { algorithm = 'ES256', secret, iss, aud, ttl: defaultTTL = 3600 * 24 } = jwtConfig\n const cookieOptions = { ...DEFAULT_COOKIE_SERIALIZE_OPTIONS, ...cookieConfig }\n\n const sessionStrategy: 'auto' | 'cookie' | 'token' = sessionConfig.strategy ?? 'auto'\n\n if (algorithm === 'ES256' && secret !== undefined && typeof secret !== 'string')\n throw new AuthError('For ES256, the secret option must be a string.')\n\n const providerMap = new Map(providers.map(p => [p.id, p]))\n\n function buildSignOptions(custom: Partial<SignOptions> = {}): SignOptions {\n const base = { ttl: custom.ttl, iss: custom.iss ?? iss, aud: custom.aud ?? aud, sub: custom.sub }\n if (algorithm === 'HS256') {\n return { algorithm, secret: custom.secret ?? secret, ...base }\n }\n else {\n if (custom.secret !== undefined && typeof custom.secret !== 'string')\n throw new AuthError('For ES256, the secret option must be a string.')\n const esSecret = custom.secret ?? secret\n return { algorithm, privateKey: custom.privateKey, secret: esSecret, ...base }\n }\n }\n\n function buildVerifyOptions(custom: Partial<VerifyOptions> = {}): VerifyOptions {\n const base = { iss: custom.iss ?? iss, aud: custom.aud ?? aud }\n if (algorithm === 'HS256') {\n return { algorithm, secret: custom.secret ?? secret, ...base }\n }\n else {\n if (custom.secret !== undefined && typeof custom.secret !== 'string')\n throw new AuthError('For ES256, the secret option must be a string.')\n const esSecret = custom.secret ?? secret\n return { algorithm, publicKey: custom.publicKey, secret: esSecret, ...base }\n }\n }\n\n async function signJWT<U extends Record<string, unknown>>(payload: U, customOptions: Partial<SignOptions> = {}): Promise<string> {\n return sign(payload, buildSignOptions(customOptions))\n }\n\n async function verifyJWT<U = Record<string, unknown>>(token: string, customOptions: Partial<VerifyOptions> = {}): Promise<U | null> {\n const options = buildVerifyOptions(customOptions)\n try {\n return await verify<U>(token, options)\n }\n catch {\n return null\n }\n }\n\n async function createSession(userId: string, data: Record<string, unknown> = {}, ttl = defaultTTL): Promise<string> {\n const payload = { sub: userId, ...data }\n return signJWT(payload, { ttl })\n }\n\n async function validateSession(token: string): Promise<GauSession | null> {\n const payload = await verifyJWT<{ sub: string } & Record<string, unknown>>(token)\n if (!payload)\n return null\n\n const userAndAccounts = await adapter.getUserAndAccounts(payload.sub)\n if (!userAndAccounts)\n return null\n\n const { user, accounts } = userAndAccounts\n return { user, session: { id: token, ...payload }, accounts }\n }\n\n return {\n ...adapter,\n providerMap: providerMap as Map<ProviderId<TProviders[number]>, TProviders[number]>,\n basePath,\n cookieOptions,\n jwt: {\n ttl: defaultTTL,\n },\n signJWT,\n verifyJWT,\n createSession,\n validateSession,\n trustHosts,\n autoLink,\n sessionStrategy,\n development: false,\n }\n}\n","import type { Auth } from '../createAuth'\nimport type { RequestLike, ResponseLike, User } from '../index'\nimport {\n CALLBACK_URI_COOKIE_NAME,\n Cookies,\n CSRF_COOKIE_NAME,\n LINKING_TOKEN_COOKIE_NAME,\n parseCookies,\n PKCE_COOKIE_NAME,\n SESSION_COOKIE_NAME,\n} from '../cookies'\nimport { json, redirect } from '../index'\n\nexport async function handleCallback(request: RequestLike, auth: Auth, providerId: string): Promise<ResponseLike> {\n const provider = auth.providerMap.get(providerId)\n if (!provider)\n return json({ error: 'Provider not found' }, { status: 400 })\n\n const url = new URL(request.url)\n const code = url.searchParams.get('code')\n const state = url.searchParams.get('state')\n\n if (!code || !state)\n return json({ error: 'Missing code or state' }, { status: 400 })\n\n const requestCookies = parseCookies(request.headers.get('Cookie'))\n const cookies = new Cookies(requestCookies, auth.cookieOptions)\n\n let savedState: string | undefined\n let redirectTo = '/'\n if (state.includes('.')) {\n const [originalSavedState, encodedRedirect] = state.split('.')\n savedState = originalSavedState\n try {\n redirectTo = atob(encodedRedirect ?? '') || '/'\n }\n catch {\n redirectTo = '/'\n }\n }\n else {\n savedState = state\n }\n\n const csrfToken = cookies.get(CSRF_COOKIE_NAME)\n\n if (!csrfToken || csrfToken !== savedState)\n return json({ error: 'Invalid CSRF token' }, { status: 403 })\n\n const codeVerifier = cookies.get(PKCE_COOKIE_NAME)\n if (!codeVerifier)\n return json({ error: 'Missing PKCE code verifier' }, { status: 400 })\n\n const callbackUri = cookies.get(CALLBACK_URI_COOKIE_NAME)\n const linkingToken = cookies.get(LINKING_TOKEN_COOKIE_NAME)\n\n if (linkingToken)\n cookies.delete(LINKING_TOKEN_COOKIE_NAME)\n\n const isLinking = !!linkingToken\n\n if (isLinking) {\n const session = await auth.validateSession(linkingToken!)\n if (!session) {\n cookies.delete(CSRF_COOKIE_NAME)\n cookies.delete(PKCE_COOKIE_NAME)\n if (callbackUri)\n cookies.delete(CALLBACK_URI_COOKIE_NAME)\n const response = redirect(redirectTo)\n cookies.toHeaders().forEach((value, key) => response.headers.append(key, value))\n return response\n }\n }\n\n const { user: providerUser, tokens } = await provider.validateCallback(code, codeVerifier, callbackUri ?? undefined)\n\n let user: User | null = null\n\n const userFromAccount = await auth.getUserByAccount(providerId, providerUser.id)\n\n if (isLinking) {\n const session = await auth.validateSession(linkingToken!)\n user = session!.user\n\n if (!user)\n return json({ error: 'User not found' }, { status: 404 })\n\n if (userFromAccount && userFromAccount.id !== user.id)\n return json({ error: 'Account already linked to another user' }, { status: 409 })\n }\n else {\n user = userFromAccount\n }\n\n if (!user) {\n const autoLink = auth.autoLink ?? 'verifiedEmail'\n const shouldLinkByEmail = providerUser.email && (\n (autoLink === 'always')\n || (autoLink === 'verifiedEmail' && providerUser.emailVerified === true)\n )\n if (shouldLinkByEmail) {\n const existingUser = await auth.getUserByEmail(providerUser.email!)\n if (existingUser) {\n // If the email is verified by the new provider, and the existing user's email is not,\n // update the user's email verification status.\n if (providerUser.emailVerified && !existingUser.emailVerified) {\n user = await auth.updateUser({\n id: existingUser.id,\n emailVerified: true,\n })\n }\n else {\n user = existingUser\n }\n }\n }\n if (!user) {\n try {\n user = await auth.createUser({\n name: providerUser.name,\n email: providerUser.email,\n image: providerUser.avatar,\n emailVerified: providerUser.emailVerified,\n })\n }\n catch (error) {\n console.error('Failed to create user:', error)\n return json({ error: 'Failed to create user' }, { status: 500 })\n }\n }\n }\n\n // self-healing: update user's email if it's missing or unverified and the provider returns a verified email\n if (user && providerUser.email) {\n const { email: currentEmail, emailVerified: currentEmailVerified } = user\n const { email: providerEmail, emailVerified: providerEmailVerified } = providerUser\n\n const update: Partial<User> & { id: string } = { id: user.id }\n let needsUpdate = false\n\n // user has no primary email. promote the provider's email.\n if (!currentEmail) {\n update.email = providerEmail\n update.emailVerified = providerEmailVerified ?? false\n needsUpdate = true\n }\n // user has an unverified primary email, and the provider confirms this same email is verified.\n else if (\n currentEmail === providerEmail\n && providerEmailVerified === true\n && !currentEmailVerified\n ) {\n update.emailVerified = true\n needsUpdate = true\n }\n\n if (needsUpdate) {\n try {\n user = await auth.updateUser(update)\n }\n catch (error) {\n console.error('Failed to update user after sign-in:', error)\n }\n }\n }\n\n if (!userFromAccount) {\n // GitHub sometimes doesn't return these which causes arctic to throw an error\n let refreshToken: string | null\n try {\n refreshToken = tokens.refreshToken()\n }\n catch {\n refreshToken = null\n }\n\n let expiresAt: number | undefined\n try {\n const expiresAtDate = tokens.accessTokenExpiresAt()\n if (expiresAtDate)\n expiresAt = Math.floor(expiresAtDate.getTime() / 1000)\n }\n catch {\n }\n\n let idToken: string | null\n try {\n idToken = tokens.idToken()\n }\n catch {\n idToken = null\n }\n\n try {\n await auth.linkAccount({\n userId: user.id,\n provider: providerId,\n providerAccountId: providerUser.id,\n accessToken: tokens.accessToken(),\n refreshToken,\n expiresAt,\n tokenType: tokens.tokenType?.() ?? null,\n scope: tokens.scopes()?.join(' ') ?? null,\n idToken,\n })\n }\n catch (error) {\n console.error('Error linking account:', error)\n return json({ error: 'Failed to link account' }, { status: 500 })\n }\n }\n\n const sessionToken = await auth.createSession(user.id)\n\n const requestUrl = new URL(request.url)\n const redirectUrl = new URL(redirectTo, request.url)\n\n const forceToken = auth.sessionStrategy === 'token'\n const forceCookie = auth.sessionStrategy === 'cookie'\n\n const isDesktopRedirect = redirectUrl.protocol === 'gau:'\n const isMobileRedirect = requestUrl.host !== redirectUrl.host\n\n // For Tauri, we can't set a cookie on a custom protocol or a different host,\n // so we pass the token in the URL. Additionally, return a small HTML page\n // that immediately navigates to the deep-link and attempts to close the window,\n // so the external OAuth tab does not stay open.\n if (forceToken || (!forceCookie && (isDesktopRedirect || isMobileRedirect))) {\n const destination = new URL(redirectUrl)\n // Use hash instead of query param for security. The hash is not sent to the server.\n destination.hash = `token=${sessionToken}`\n\n const html = `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"utf-8\" />\n <title>Authentication Complete</title>\n <style>\n body {\n font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n background-color: #09090b;\n color: #fafafa;\n display: flex;\n justify-content: center;\n align-items: center;\n height: 100vh;\n margin: 0;\n text-align: center;\n }\n .card {\n background-color: #18181b;\n border: 1px solid #27272a;\n border-radius: 0.75rem;\n padding: 2rem;\n max-width: 320px;\n }\n h1 {\n font-size: 1.25rem;\n font-weight: 600;\n margin: 0 0 0.5rem;\n }\n p {\n margin: 0;\n color: #a1a1aa;\n }\n </style>\n <script>\n window.onload = function() {\n const url = ${JSON.stringify(destination.toString())};\n window.location.href = url;\n setTimeout(window.close, 500);\n };\n </script>\n</head>\n<body>\n <div class=\"card\">\n <h1>Authentication Successful</h1>\n <p>You can now close this window.</p>\n </div>\n</body>\n</html>`\n\n // Clear temporary cookies (CSRF/PKCE/Callback URI) so they don't linger\n cookies.delete(CSRF_COOKIE_NAME)\n cookies.delete(PKCE_COOKIE_NAME)\n if (callbackUri)\n cookies.delete(CALLBACK_URI_COOKIE_NAME)\n\n const response = new Response(html, {\n status: 200,\n headers: { 'Content-Type': 'text/html; charset=utf-8' },\n })\n cookies.toHeaders().forEach((value, key) => {\n response.headers.append(key, value)\n })\n return response\n }\n\n cookies.set(SESSION_COOKIE_NAME, sessionToken, {\n maxAge: auth.jwt.ttl,\n sameSite: auth.development ? 'lax' : 'none',\n secure: !auth.development,\n })\n cookies.delete(CSRF_COOKIE_NAME)\n cookies.delete(PKCE_COOKIE_NAME)\n if (callbackUri)\n cookies.delete(CALLBACK_URI_COOKIE_NAME)\n\n const redirectParam = url.searchParams.get('redirect')\n\n let response: Response\n if (redirectParam === 'false') {\n const accounts = await auth.getAccounts(user.id)\n response = json({ user: { ...user, accounts } })\n }\n else {\n response = redirect(redirectTo)\n }\n\n cookies.toHeaders().forEach((value, key) => {\n response.headers.append(key, value)\n })\n\n return response\n}\n","import type { RequestLike } from '../index'\n\nexport function applyCors(request: RequestLike, response: Response): Response {\n const origin = request.headers.get('Origin') || request.headers.get('origin')\n if (!origin)\n return response\n response.headers.set('Access-Control-Allow-Origin', origin)\n response.headers.set('Vary', 'Origin')\n response.headers.set('Access-Control-Allow-Credentials', 'true')\n response.headers.set('Access-Control-Allow-Headers', 'Content-Type, Authorization, Cookie')\n response.headers.set('Access-Control-Allow-Methods', 'GET, POST, OPTIONS')\n return response\n}\n\nexport function handlePreflight(request: RequestLike): Response {\n const origin = request.headers.get('Origin') || request.headers.get('origin') || '*'\n return new Response(null, {\n status: 204,\n headers: {\n 'Access-Control-Allow-Origin': origin,\n 'Access-Control-Allow-Credentials': 'true',\n 'Access-Control-Allow-Headers': 'Content-Type, Authorization, Cookie',\n 'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',\n },\n })\n}\n","import { generateCodeVerifier, generateState } from 'arctic'\n\nexport function createOAuthUris() {\n const state = generateState()\n const codeVerifier = generateCodeVerifier()\n\n return {\n state,\n codeVerifier,\n }\n}\n","import type { Auth } from '../createAuth'\nimport type { RequestLike, ResponseLike } from '../index'\nimport { createOAuthUris } from '../../oauth/utils'\nimport {\n CALLBACK_URI_COOKIE_NAME,\n Cookies,\n CSRF_COOKIE_NAME,\n CSRF_MAX_AGE,\n LINKING_TOKEN_COOKIE_NAME,\n parseCookies,\n PKCE_COOKIE_NAME,\n} from '../cookies'\nimport { json, redirect } from '../index'\n\nexport function verifyRequestOrigin(request: RequestLike, trustHosts: 'all' | string[], development: boolean): boolean {\n if (trustHosts === 'all')\n return true\n\n const origin = request.headers.get('origin')\n\n if (!origin)\n return false\n\n let originHost: string\n try {\n originHost = new URL(origin).host\n }\n catch {\n return false\n }\n\n if (development) {\n const isLocal = originHost.startsWith('localhost') || originHost.startsWith('127.0.0.1')\n if (isLocal)\n return true\n }\n\n const requestUrl = new URL(request.url)\n const requestHost = requestUrl.host\n const requestOrigin = `${requestUrl.protocol}//${requestHost}`\n\n if (origin === requestOrigin)\n return true\n\n return trustHosts.includes(originHost)\n}\n\nexport async function prepareOAuthRedirect(\n request: RequestLike,\n auth: Auth,\n providerId: string,\n linkingToken: string | null,\n): Promise<ResponseLike> {\n const provider = auth.providerMap.get(providerId)\n if (!provider)\n return json({ error: 'Provider not found' }, { status: 400 })\n\n const { state: originalState, codeVerifier } = createOAuthUris()\n const url = new URL(request.url)\n const redirectTo = url.searchParams.get('redirectTo')\n\n if (redirectTo) {\n let parsedRedirect: URL\n try {\n if (redirectTo.startsWith('//'))\n throw new Error('Protocol-relative URL not allowed')\n parsedRedirect = new URL(redirectTo, url.origin)\n }\n catch {\n return json({ error: 'Invalid \"redirectTo\" URL' }, { status: 400 })\n }\n\n const redirectHost = parsedRedirect.host\n const currentHost = new URL(request.url).host\n\n const isSameHost = redirectHost === currentHost\n const isTrusted = auth.trustHosts === 'all' || auth.trustHosts.includes(redirectHost)\n const isHttp = parsedRedirect.protocol === 'http:' || parsedRedirect.protocol === 'https:'\n\n if (isHttp && !isSameHost && !isTrusted)\n return json({ error: 'Untrusted redirect host' }, { status: 400 })\n }\n\n const state = redirectTo ? `${originalState}.${btoa(redirectTo)}` : originalState\n let callbackUri = url.searchParams.get('callbackUri')\n if (!callbackUri && provider.requiresRedirectUri)\n callbackUri = `${url.origin}${auth.basePath}/${providerId}/callback`\n\n let authUrl: URL | null\n try {\n authUrl = await provider.getAuthorizationUrl(state, codeVerifier, {\n redirectUri: callbackUri ?? undefined,\n })\n }\n catch (error) {\n console.error('Error getting authorization URL:', error)\n authUrl = null\n }\n\n if (!authUrl)\n return json({ error: 'Could not create authorization URL' }, { status: 500 })\n\n const requestCookies = parseCookies(request.headers.get('Cookie'))\n const cookies = new Cookies(requestCookies, auth.cookieOptions)\n\n const temporaryCookieOptions = {\n maxAge: CSRF_MAX_AGE,\n sameSite: auth.development ? 'lax' : 'none',\n secure: !auth.development,\n } as const\n\n cookies.set(CSRF_COOKIE_NAME, originalState, temporaryCookieOptions)\n cookies.set(PKCE_COOKIE_NAME, codeVerifier, temporaryCookieOptions)\n if (linkingToken)\n cookies.set(LINKING_TOKEN_COOKIE_NAME, linkingToken, temporaryCookieOptions)\n\n if (callbackUri)\n cookies.set(CALLBACK_URI_COOKIE_NAME, callbackUri, temporaryCookieOptions)\n\n const redirectParam = url.searchParams.get('redirect')\n\n if (redirectParam === 'false') {\n const response = json({ url: authUrl.toString() })\n cookies.toHeaders().forEach((value, key) => {\n response.headers.append(key, value)\n })\n return response\n }\n\n const response = redirect(authUrl.toString())\n cookies.toHeaders().forEach((value, key) => {\n response.headers.append(key, value)\n })\n\n return response\n}\n","import type { Auth } from '../createAuth'\nimport type { RequestLike, ResponseLike } from '../index'\nimport { parseCookies, SESSION_COOKIE_NAME } from '../cookies'\nimport { json } from '../index'\nimport { prepareOAuthRedirect } from './utils'\n\nexport async function handleLink(request: RequestLike, auth: Auth, providerId: string): Promise<ResponseLike> {\n const url = new URL(request.url)\n const requestCookies = parseCookies(request.headers.get('Cookie'))\n let sessionToken = requestCookies.get(SESSION_COOKIE_NAME)\n\n if (!sessionToken) {\n const authHeader = request.headers.get('Authorization')\n if (authHeader?.startsWith('Bearer '))\n sessionToken = authHeader.substring(7)\n }\n\n if (!sessionToken)\n sessionToken = url.searchParams.get('token') ?? undefined\n\n if (!sessionToken)\n return json({ error: 'Unauthorized' }, { status: 401 })\n\n const session = await auth.validateSession(sessionToken)\n if (!session)\n return json({ error: 'Unauthorized' }, { status: 401 })\n\n url.searchParams.delete('token')\n const cleanRequest = new Request(url.toString(), request as Request)\n\n return prepareOAuthRedirect(cleanRequest, auth, providerId, sessionToken)\n}\n\nexport async function handleUnlink(request: RequestLike, auth: Auth, providerId: string): Promise<ResponseLike> {\n const requestCookies = parseCookies(request.headers.get('Cookie'))\n let sessionToken = requestCookies.get(SESSION_COOKIE_NAME)\n\n if (!sessionToken) {\n const authHeader = request.headers.get('Authorization')\n if (authHeader?.startsWith('Bearer '))\n sessionToken = authHeader.substring(7)\n }\n\n if (!sessionToken)\n return json({ error: 'Unauthorized' }, { status: 401 })\n\n const session = await auth.validateSession(sessionToken)\n if (!session || !session.user)\n return json({ error: 'Unauthorized' }, { status: 401 })\n\n const accounts = session.accounts ?? []\n\n if (accounts.length <= 1)\n return json({ error: 'Cannot unlink the last account' }, { status: 400 })\n\n const accountToUnlink = accounts.find(a => a.provider === providerId)\n if (!accountToUnlink)\n return json({ error: `Provider \"${providerId}\" not linked to this account` }, { status: 400 })\n\n await auth.unlinkAccount(providerId, accountToUnlink.providerAccountId)\n\n const remainingAccounts = await auth.getAccounts(session.user.id)\n\n // if there are remaining accounts, we need to potentially update the user's primary info\n // TODO: for now we just clear the email\n if (remainingAccounts.length > 0 && session.user.email) {\n try {\n await auth.updateUser({\n id: session.user.id,\n email: null,\n emailVerified: false,\n })\n }\n catch (error) {\n console.error('Failed to clear stale email after unlinking:', error)\n }\n }\n\n return json({ message: 'Account unlinked successfully' })\n}\n","import type { Auth } from '../createAuth'\nimport type { RequestLike, ResponseLike } from '../index'\nimport { Cookies, parseCookies, SESSION_COOKIE_NAME } from '../cookies'\n\nimport { json } from '../index'\nimport { prepareOAuthRedirect } from './utils'\n\nexport async function handleSignIn(request: RequestLike, auth: Auth, providerId: string): Promise<ResponseLike> {\n return prepareOAuthRedirect(request, auth, providerId, null)\n}\n\nexport async function handleSignOut(request: RequestLike, auth: Auth): Promise<ResponseLike> {\n const requestCookies = parseCookies(request.headers.get('Cookie'))\n const cookies = new Cookies(requestCookies, auth.cookieOptions)\n cookies.delete(SESSION_COOKIE_NAME, {\n sameSite: auth.development ? 'lax' : 'none',\n secure: !auth.development,\n })\n\n const response = json({ message: 'Signed out' })\n cookies.toHeaders().forEach((value, key) => {\n response.headers.append(key, value)\n })\n\n return response\n}\n","import type { Auth } from '../createAuth'\nimport type { RequestLike, ResponseLike } from '../index'\nimport { parseCookies, SESSION_COOKIE_NAME } from '../cookies'\nimport { json, NULL_SESSION } from '../index'\n\nexport async function handleSession(request: RequestLike, auth: Auth): Promise<ResponseLike> {\n const rawCookieHeader = request.headers.get('Cookie')\n const requestCookies = parseCookies(rawCookieHeader)\n let sessionToken = requestCookies.get(SESSION_COOKIE_NAME)\n\n if (!sessionToken) {\n const authHeader = request.headers.get('Authorization')\n if (authHeader?.startsWith('Bearer '))\n sessionToken = authHeader.substring(7)\n }\n\n const providers = Array.from(auth.providerMap.keys())\n\n if (!sessionToken)\n return json({ ...NULL_SESSION, providers })\n\n try {\n const sessionData = await auth.validateSession(sessionToken)\n\n if (!sessionData)\n return json({ ...NULL_SESSION, providers }, { status: 401 })\n\n return json({ ...sessionData, providers })\n }\n catch (error) {\n console.error('Error validating session:', error)\n return json({ error: 'Failed to validate session' }, { status: 500 })\n }\n}\n","import type { Auth } from './createAuth'\nimport type { RequestLike, ResponseLike } from './index'\nimport {\n applyCors,\n handleCallback,\n handleLink,\n handlePreflight,\n handleSession,\n handleSignIn,\n handleSignOut,\n handleUnlink,\n verifyRequestOrigin,\n} from './handlers'\nimport { json } from './index'\n\nexport function createHandler(auth: Auth): (request: RequestLike) => Promise<ResponseLike> {\n const { basePath } = auth\n\n return async function (request: RequestLike): Promise<ResponseLike> {\n // Handle preflight requests early\n if (request.method === 'OPTIONS')\n return handlePreflight(request)\n\n const url = new URL(request.url)\n if (!url.pathname.startsWith(basePath))\n return applyCors(request, json({ error: 'Not Found' }, { status: 404 }))\n\n if (request.method === 'POST' && !verifyRequestOrigin(request, auth.trustHosts, auth.development)) {\n if (auth.development) {\n const origin = request.headers.get('origin') ?? 'N/A'\n const message = `Untrusted origin: '${origin}'. Add this origin to 'trustHosts' in createAuth() or ensure you are using 'localhost' or '127.0.0.1' for development.`\n return applyCors(request, json({ error: 'Forbidden', message }, { status: 403 }))\n }\n return applyCors(request, json({ error: 'Forbidden' }, { status: 403 }))\n }\n\n const path = url.pathname.substring(basePath.length)\n const parts = path.split('/').filter(Boolean)\n const action = parts[0]\n\n if (!action)\n return applyCors(request, json({ error: 'Not Found' }, { status: 404 }))\n\n let response: ResponseLike\n\n if (request.method === 'GET') {\n if (action === 'session')\n response = await handleSession(request, auth)\n else if (parts.length === 2 && parts[0] === 'link')\n response = await handleLink(request, auth, parts[1] as string)\n else if (parts.length === 2 && parts[1] === 'callback')\n response = await handleCallback(request, auth, action)\n else if (parts.length === 1)\n response = await handleSignIn(request, auth, action)\n else\n response = json({ error: 'Not Found' }, { status: 404 })\n }\n else if (request.method === 'POST') {\n if (parts.length === 1 && action === 'signout')\n response = await handleSignOut(request, auth)\n else if (parts.length === 2 && parts[0] === 'unlink')\n response = await handleUnlink(request, auth, parts[1] as string)\n else\n response = json({ error: 'Not Found' }, { status: 404 })\n }\n else {\n response = json({ error: 'Method Not Allowed' }, { status: 405 })\n }\n\n return applyCors(request, response as Response)\n }\n}\n","export interface RequestLike {\n /** Absolute or relative URL */\n readonly url: string\n /** Upper-case HTTP method (e.g. `GET`) */\n readonly method: string\n /** All HTTP headers – mutable so adapters can append */\n readonly headers: Headers\n /** Lazily parse the body as JSON */\n json: <T = unknown>() => Promise<T>\n /** Raw text body */\n text: () => Promise<string>\n /** FormData helper (for `application/x-www-form-urlencoded` or `multipart/form-data`) */\n formData: () => Promise<FormData>\n}\n\nexport interface ResponseLike {\n readonly status: number\n readonly headers: Headers\n readonly body?: BodyInit | null\n json: <T = unknown>() => Promise<T>\n text: () => Promise<string>\n}\n\nexport interface User {\n id: string\n name?: string | null\n email?: string | null\n emailVerified?: boolean | null\n image?: string | null\n}\n\nexport interface Session {\n id: string\n sub: string\n [key: string]: unknown\n}\n\nexport interface GauSession<TProviders extends string = string> {\n user: User | null\n session: Session | null\n accounts?: Account[] | null\n providers?: TProviders[]\n}\n\nexport const NULL_SESSION = {\n user: null,\n session: null,\n accounts: null,\n} as const\n\nexport interface NewUser extends Omit<User, 'id' | 'accounts'> {\n id?: string\n}\n\nexport interface Account {\n userId: string\n provider: string\n providerAccountId: string\n type?: string // e.g. \"oauth\"\n accessToken?: string | null\n refreshToken?: string | null\n expiresAt?: number | null // epoch seconds\n idToken?: string | null\n scope?: string | null\n tokenType?: string | null\n sessionState?: string | null\n}\n\nexport interface NewAccount extends Account {}\n\nexport interface Adapter {\n getUser: (id: string) => Promise<User | null>\n getUserByEmail: (email: string) => Promise<User | null>\n getUserByAccount: (provider: string, providerAccountId: string) => Promise<User | null>\n getAccounts: (userId: string) => Promise<Account[]>\n getUserAndAccounts: (userId: string) => Promise<{ user: User, accounts: Account[] } | null>\n createUser: (data: NewUser) => Promise<User>\n linkAccount: (data: NewAccount) => Promise<void>\n unlinkAccount: (provider: string, providerAccountId: string) => Promise<void>\n updateUser: (data: Partial<User> & { id: string }) => Promise<User>\n deleteUser: (id: string) => Promise<void>\n}\n\nexport class AuthError extends Error {\n override readonly cause?: unknown\n constructor(message: string, cause?: unknown) {\n super(message)\n this.name = 'AuthError'\n this.cause = cause\n }\n}\n\nexport function json<T>(data: T, init: ResponseInit = {}): Response {\n const headers = new Headers(init.headers)\n if (!headers.has('Content-Type'))\n headers.set('Content-Type', 'application/json; charset=utf-8')\n return new Response(JSON.stringify(data), { ...init, headers })\n}\n\nexport function redirect(url: string, status: 302 | 303 = 302): Response {\n return new Response(null, {\n status,\n headers: {\n Location: url,\n },\n })\n}\n\nexport * from './cookies'\nexport * from './createAuth'\nexport * from './handler'\n","import { AuthError } from '../core/index'\n\nexport function constantTimeEqual(a: Uint8Array, b: Uint8Array): boolean {\n let diff = a.length ^ b.length\n const len = Math.max(a.length, b.length)\n for (let i = 0; i < len; i++)\n diff |= (a[i] ?? 0) ^ (b[i] ?? 0)\n\n return diff === 0\n}\n\nfunction base64UrlToArray(base64Url: string): Uint8Array {\n const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/')\n const padLength = (4 - (base64.length % 4)) % 4\n const padded = base64.padEnd(base64.length + padLength, '=')\n try {\n const binary_string = atob(padded)\n const len = binary_string.length\n const bytes = new Uint8Array(len)\n for (let i = 0; i < len; i++)\n bytes[i] = binary_string.charCodeAt(i)\n\n return bytes\n }\n catch {\n throw new AuthError('Invalid base64url string')\n }\n}\n\nexport async function deriveKeysFromSecret(secret: string): Promise<{ privateKey: CryptoKey, publicKey: CryptoKey }> {\n try {\n const secretBytes = base64UrlToArray(secret)\n const privateKey = await crypto.subtle.importKey(\n 'pkcs8',\n secretBytes.slice(),\n { name: 'ECDSA', namedCurve: 'P-256' },\n true,\n ['sign'],\n )\n\n const jwk = await crypto.subtle.exportKey('jwk', privateKey)\n delete jwk.d\n jwk.key_ops = ['verify']\n\n const publicKey = await crypto.subtle.importKey(\n 'jwk',\n jwk,\n { name: 'ECDSA', namedCurve: 'P-256' },\n true,\n ['verify'],\n )\n return { privateKey, publicKey }\n }\n catch (error) {\n if (error instanceof AuthError)\n throw error\n throw new AuthError('Invalid secret. Must be a base64url-encoded PKCS#8 private key for ES256. Use `bunx gau secret` to generate one.', error)\n }\n}\n\n/**\n * Convert JWS raw signature (r || s) to DER-encoded format for WebCrypto.\n */\nexport function rawToDer(raw: Uint8Array): Uint8Array {\n if (raw.length !== 64)\n throw new Error('Invalid raw signature length')\n\n let r = raw.slice(0, 32)\n let s = raw.slice(32)\n\n let rOffset = 0\n while (rOffset < r.length - 1 && r[rOffset] === 0) rOffset++\n r = r.slice(rOffset)\n\n let sOffset = 0\n while (sOffset < s.length - 1 && s[sOffset] === 0) sOffset++\n s = s.slice(sOffset)\n\n if (r.length > 0 && r[0]! & 0x80) {\n const rPadded = new Uint8Array(r.length + 1)\n rPadded[0] = 0\n rPadded.set(r, 1)\n r = rPadded\n }\n if (s.length > 0 && s[0]! & 0x80) {\n const sPadded = new Uint8Array(s.length + 1)\n sPadded[0] = 0\n sPadded.set(s, 1)\n s = sPadded\n }\n\n const rLength = r.length\n const sLength = s.length\n const totalLength = 2 + rLength + 2 + sLength\n\n const der = new Uint8Array(2 + totalLength)\n der[0] = 0x30 // SEQUENCE\n der[1] = totalLength\n der[2] = 0x02 // INTEGER\n der[3] = rLength\n der.set(r, 4)\n der[4 + rLength] = 0x02 // INTEGER\n der[5 + rLength] = sLength\n der.set(s, 6 + rLength)\n\n return der\n}\n"],"mappings":"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","names":["response","response"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/adapters/memory/index.ts"],"sourcesContent":["import type { Account, Adapter, NewAccount, NewUser, User } from '../../core/index'\n\ninterface InternalAccountKey {\n provider: string\n providerAccountId: string\n}\n\nfunction accountKey(k: InternalAccountKey): string {\n return `${k.provider}:${k.providerAccountId}`\n}\n\nexport function MemoryAdapter(): Adapter {\n const users = new Map<string, User>()\n const usersByEmail = new Map<string, string>() // email -> userId\n const accounts = new Map<string, string>() // accountKey -> userId\n\n return {\n async getUser(id) {\n return users.get(id) ?? null\n },\n\n async getUserByEmail(email) {\n const id = usersByEmail.get(email)\n if (!id)\n return null\n return users.get(id) ?? null\n },\n\n async getUserByAccount(provider, providerAccountId) {\n const id = accounts.get(accountKey({ provider, providerAccountId }))\n if (!id)\n return null\n return users.get(id) ?? null\n },\n\n async getAccounts(userId) {\n const userAccounts: Account[] = []\n for (const [key, accUserId] of accounts.entries()) {\n if (accUserId === userId) {\n const [provider, providerAccountId] = key.split(':') as [string, string]\n userAccounts.push({ userId, provider, providerAccountId })\n }\n }\n return userAccounts\n },\n\n async getUserAndAccounts(userId) {\n const user = await this.getUser(userId)\n if (!user)\n return null\n const accounts = await this.getAccounts(userId)\n return { user, accounts }\n },\n\n async createUser(data: NewUser) {\n const id = data.id ?? crypto.randomUUID()\n const user: User = {\n id,\n name: data.name ?? null,\n email: data.email ?? null,\n image: data.image ?? null,\n emailVerified: null,\n }\n users.set(id, user)\n if (user.email)\n usersByEmail.set(user.email, id)\n return user\n },\n\n async linkAccount(data: NewAccount) {\n accounts.set(accountKey(data), data.userId)\n },\n\n async unlinkAccount(provider, providerAccountId) {\n accounts.delete(accountKey({ provider, providerAccountId }))\n },\n\n async updateUser(partial) {\n const existing = users.get(partial.id)\n if (!existing)\n throw new Error('User not found')\n const updated: User = { ...existing, ...partial }\n users.set(updated.id, updated)\n if (updated.email)\n usersByEmail.set(updated.email, updated.id)\n return updated\n },\n async deleteUser(id) {\n const user = users.get(id)\n if (user?.email)\n usersByEmail.delete(user.email)\n users.delete(id)\n for (const [key, userId] of accounts.entries()) {\n if (userId === id)\n accounts.delete(key)\n }\n },\n }\n}\n"],"mappings":";AAOA,SAAS,WAAW,GAA+B;AACjD,SAAO,GAAG,EAAE,QAAQ,IAAI,EAAE,iBAAiB;AAC7C;AAEO,SAAS,gBAAyB;AACvC,QAAM,QAAQ,oBAAI,IAAkB;AACpC,QAAM,eAAe,oBAAI,IAAoB;AAC7C,QAAM,WAAW,oBAAI,IAAoB;AAEzC,SAAO;AAAA,IACL,MAAM,QAAQ,IAAI;AAChB,aAAO,MAAM,IAAI,EAAE,KAAK;AAAA,IAC1B;AAAA,IAEA,MAAM,eAAe,OAAO;AAC1B,YAAM,KAAK,aAAa,IAAI,KAAK;AACjC,UAAI,CAAC;AACH,eAAO;AACT,aAAO,MAAM,IAAI,EAAE,KAAK;AAAA,IAC1B;AAAA,IAEA,MAAM,iBAAiB,UAAU,mBAAmB;AAClD,YAAM,KAAK,SAAS,IAAI,WAAW,EAAE,UAAU,kBAAkB,CAAC,CAAC;AACnE,UAAI,CAAC;AACH,eAAO;AACT,aAAO,MAAM,IAAI,EAAE,KAAK;AAAA,IAC1B;AAAA,IAEA,MAAM,YAAY,QAAQ;AACxB,YAAM,eAA0B,CAAC;AACjC,iBAAW,CAAC,KAAK,SAAS,KAAK,SAAS,QAAQ,GAAG;AACjD,YAAI,cAAc,QAAQ;AACxB,gBAAM,CAAC,UAAU,iBAAiB,IAAI,IAAI,MAAM,GAAG;AACnD,uBAAa,KAAK,EAAE,QAAQ,UAAU,kBAAkB,CAAC;AAAA,QAC3D;AAAA,MACF;AACA,aAAO;AAAA,IACT;AAAA,IAEA,MAAM,mBAAmB,QAAQ;AAC/B,YAAM,OAAO,MAAM,KAAK,QAAQ,MAAM;AACtC,UAAI,CAAC;AACH,eAAO;AACT,YAAMA,YAAW,MAAM,KAAK,YAAY,MAAM;AAC9C,aAAO,EAAE,MAAM,UAAAA,UAAS;AAAA,IAC1B;AAAA,IAEA,MAAM,WAAW,MAAe;AAC9B,YAAM,KAAK,KAAK,MAAM,OAAO,WAAW;AACxC,YAAM,OAAa;AAAA,QACjB;AAAA,QACA,MAAM,KAAK,QAAQ;AAAA,QACnB,OAAO,KAAK,SAAS;AAAA,QACrB,OAAO,KAAK,SAAS;AAAA,QACrB,eAAe;AAAA,MACjB;AACA,YAAM,IAAI,IAAI,IAAI;AAClB,UAAI,KAAK;AACP,qBAAa,IAAI,KAAK,OAAO,EAAE;AACjC,aAAO;AAAA,IACT;AAAA,IAEA,MAAM,YAAY,MAAkB;AAClC,eAAS,IAAI,WAAW,IAAI,GAAG,KAAK,MAAM;AAAA,IAC5C;AAAA,IAEA,MAAM,cAAc,UAAU,mBAAmB;AAC/C,eAAS,OAAO,WAAW,EAAE,UAAU,kBAAkB,CAAC,CAAC;AAAA,IAC7D;AAAA,IAEA,MAAM,WAAW,SAAS;AACxB,YAAM,WAAW,MAAM,IAAI,QAAQ,EAAE;AACrC,UAAI,CAAC;AACH,cAAM,IAAI,MAAM,gBAAgB;AAClC,YAAM,UAAgB,EAAE,GAAG,UAAU,GAAG,QAAQ;AAChD,YAAM,IAAI,QAAQ,IAAI,OAAO;AAC7B,UAAI,QAAQ;AACV,qBAAa,IAAI,QAAQ,OAAO,QAAQ,EAAE;AAC5C,aAAO;AAAA,IACT;AAAA,IACA,MAAM,WAAW,IAAI;AACnB,YAAM,OAAO,MAAM,IAAI,EAAE;AACzB,UAAI,MAAM;AACR,qBAAa,OAAO,KAAK,KAAK;AAChC,YAAM,OAAO,EAAE;AACf,iBAAW,CAAC,KAAK,MAAM,KAAK,SAAS,QAAQ,GAAG;AAC9C,YAAI,WAAW;AACb,mBAAS,OAAO,GAAG;AAAA,MACvB;AAAA,IACF;AAAA,EACF;AACF;","names":["accounts"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/adapters/drizzle/index.ts","../src/adapters/drizzle/mysql.ts","../src/adapters/drizzle/pg.ts","../src/adapters/drizzle/sqlite.ts","../src/adapters/drizzle/transaction.ts"],"sourcesContent":["import type { Adapter } from '../../core/index'\nimport type { AccountsTable, UsersTable } from './sqlite'\nimport { is } from 'drizzle-orm'\nimport { MySqlDatabase } from 'drizzle-orm/mysql-core'\nimport { PgDatabase } from 'drizzle-orm/pg-core'\n\nimport { BaseSQLiteDatabase } from 'drizzle-orm/sqlite-core'\nimport { MySqlDrizzleAdapter } from './mysql'\nimport { PostgresDrizzleAdapter } from './pg'\nimport { SQLiteDrizzleAdapter } from './sqlite'\n\nexport function DrizzleAdapter<\n U extends UsersTable,\n A extends AccountsTable,\n>(\n db:\n | BaseSQLiteDatabase<'sync' | 'async', any, any>\n | MySqlDatabase<any, any, any, any>\n | PgDatabase<any, any, any>,\n users: U,\n accounts: A,\n): Adapter {\n if (is(db, BaseSQLiteDatabase))\n return SQLiteDrizzleAdapter(db, users, accounts)\n\n if (is(db, MySqlDatabase))\n // @ts-expect-error Not implemented\n return MySqlDrizzleAdapter(db, users, accounts)\n\n if (is(db, PgDatabase))\n // @ts-expect-error Not implemented\n return PostgresDrizzleAdapter(db, users, accounts)\n\n throw new Error(\n `Unsupported database type (${typeof db}) in gau Drizzle adapter.`,\n )\n}\n","// TODO: Implement MySQL adapter for gau\nexport function MySqlDrizzleAdapter(): never {\n throw new Error('MySQL adapter is not yet implemented.')\n}\n","// TODO: Implement PostgreSQL adapter for gau\nexport function PostgresDrizzleAdapter(): never {\n throw new Error('PostgreSQL adapter is not yet implemented.')\n}\n","import type { AnyColumn, InferInsertModel, InferSelectModel, Table } from 'drizzle-orm'\nimport type { BaseSQLiteDatabase } from 'drizzle-orm/sqlite-core'\nimport type { Account, Adapter, NewAccount, NewUser, User } from '../../core/index'\nimport { and, eq } from 'drizzle-orm'\nimport { transaction } from './transaction'\n\nexport type UsersTable = Table & {\n id: AnyColumn\n name: AnyColumn\n email: AnyColumn\n image: AnyColumn\n emailVerified: AnyColumn\n createdAt: AnyColumn\n updatedAt: AnyColumn\n}\n\nexport type AccountsTable = Table & {\n userId: AnyColumn\n provider: AnyColumn\n providerAccountId: AnyColumn\n}\n\n/**\n * SQLite-specific Drizzle adapter.\n *\n * Pass concrete `users` and `accounts` `Table` objects\n * with the columns we access (`id`, `email`, `userId`, `provider`, `providerAccountId`).\n */\nexport function SQLiteDrizzleAdapter<\n DB extends BaseSQLiteDatabase<'sync' | 'async', any, any>,\n U extends UsersTable,\n A extends AccountsTable,\n>(db: DB, Users: U, Accounts: A): Adapter {\n type DBUser = InferSelectModel<U>\n type DBAccount = InferSelectModel<A>\n type DBInsertUser = InferInsertModel<U>\n type DBInsertAccount = InferInsertModel<A>\n\n const toUser = (row: DBUser | undefined | null): User | null =>\n row ? ({ ...(row as any) }) : null\n\n return {\n async getUser(id) {\n const user: DBUser | undefined = await db\n .select()\n .from(Users)\n .where(eq(Users.id, id))\n .get()\n return toUser(user)\n },\n\n async getUserByEmail(email) {\n const user: DBUser | undefined = await db\n .select()\n .from(Users)\n .where(eq(Users.email, email))\n .get()\n return toUser(user)\n },\n\n async getUserByAccount(provider, providerAccountId) {\n const result: DBUser | undefined = await db\n .select()\n .from(Users)\n .innerJoin(Accounts, eq(Users.id, Accounts.userId))\n .where(and(eq(Accounts.provider, provider), eq(Accounts.providerAccountId, providerAccountId)))\n .get()\n return toUser(result?.users)\n },\n\n async getAccounts(userId) {\n const accounts: DBAccount[] = await db\n .select()\n .from(Accounts)\n .where(eq(Accounts.userId, userId))\n .all()\n return accounts as Account[]\n },\n\n async getUserAndAccounts(userId) {\n const result = await db\n .select()\n .from(Users)\n .where(eq(Users.id, userId))\n .leftJoin(Accounts, eq(Users.id, Accounts.userId))\n .all()\n\n if (!result.length)\n return null\n\n const user = toUser(result[0]!.users)!\n const accounts = result\n .map(row => row.accounts)\n .filter(Boolean) as Account[]\n\n return { user, accounts }\n },\n\n async createUser(data: NewUser) {\n const id = data.id ?? crypto.randomUUID()\n return await transaction(db, async (tx) => {\n await tx\n .insert(Users)\n .values({\n id,\n name: data.name ?? null,\n email: data.email ?? null,\n image: data.image ?? null,\n emailVerified: data.emailVerified ?? null,\n createdAt: new Date(),\n updatedAt: new Date(),\n } as DBInsertUser)\n .run()\n\n const result: DBUser | undefined = await tx.select().from(Users).where(eq(Users.id, id)).get()\n return toUser(result) as User\n })\n },\n\n async linkAccount(data: NewAccount) {\n await db\n .insert(Accounts)\n .values({\n type: 'oauth',\n ...data,\n } as DBInsertAccount)\n .run()\n },\n\n async unlinkAccount(provider, providerAccountId) {\n await db\n .delete(Accounts)\n .where(and(eq(Accounts.provider, provider), eq(Accounts.providerAccountId, providerAccountId)))\n .run()\n },\n\n async updateUser(partial) {\n return await transaction(db, async (tx) => {\n await tx\n .update(Users)\n .set({\n name: partial.name,\n email: partial.email,\n image: partial.image,\n emailVerified: partial.emailVerified,\n updatedAt: new Date(),\n } as Partial<DBInsertUser>)\n .where(eq(Users.id, partial.id))\n .run()\n\n const result: DBUser | undefined = await tx.select().from(Users).where(eq(Users.id, partial.id)).get()\n return toUser(result) as User\n })\n },\n\n async deleteUser(id) {\n await db.delete(Users).where(eq(Users.id, id)).run()\n },\n }\n}\n","import type { BaseSQLiteDatabase } from 'drizzle-orm/sqlite-core'\nimport { sql } from 'drizzle-orm'\n\n/**\n * A helper to run transactions across both sync (`better-sqlite3`)\n * and async (`libsql`) Drizzle drivers.\n *\n * It checks for the `mode` property on the Drizzle DB instance, which is\n * `'sync'` or `'async'`.\n *\n * @param db The Drizzle database instance.\n * @param callback The function to execute within the transaction.\n */\nexport async function transaction<T>(\n db: BaseSQLiteDatabase<'sync' | 'async', any, any>,\n callback: (\n tx: Omit<typeof db, 'transaction'>,\n ) => Promise<T>,\n): Promise<T> {\n const isAsync = (db as any).session?.mode === 'async' || (db as any).mode === 'async'\n\n if (isAsync)\n return db.transaction(callback)\n\n db.run(sql`BEGIN`)\n try {\n const result = await callback(db)\n db.run(sql`COMMIT`)\n return result\n }\n catch (e) {\n db.run(sql`ROLLBACK`)\n throw e\n }\n}\n"],"mappings":"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","names":[]}
|