@absolutejs/auth 0.56.18 → 0.57.0

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.
Files changed (54) hide show
  1. package/dist/agents/index.js +44 -37
  2. package/dist/agents/index.js.map +7 -7
  3. package/dist/audit/postgresAuditStore.d.ts +1 -1
  4. package/dist/audit/types.d.ts +2 -0
  5. package/dist/audit/wrap.d.ts +4 -2
  6. package/dist/cli/import/auth0.d.ts +1 -1
  7. package/dist/cli/import/clerk.d.ts +1 -1
  8. package/dist/cli/import/lucia.d.ts +1 -1
  9. package/dist/cli/import/nextauth.d.ts +1 -1
  10. package/dist/cli/import/types.d.ts +1 -0
  11. package/dist/cli/migrate.js +91 -47
  12. package/dist/cli/migrate.js.map +14 -13
  13. package/dist/client/createAuthClient.d.ts +3 -2
  14. package/dist/client/index.js +9 -498
  15. package/dist/client/index.js.map +5 -20
  16. package/dist/client/react.d.ts +21 -21
  17. package/dist/client/react.js +40 -531
  18. package/dist/client/react.js.map +8 -23
  19. package/dist/client/solid.d.ts +21 -21
  20. package/dist/client/solid.js +29 -518
  21. package/dist/client/solid.js.map +5 -20
  22. package/dist/client/svelte.d.ts +21 -21
  23. package/dist/client/svelte.js +30 -519
  24. package/dist/client/svelte.js.map +5 -20
  25. package/dist/client/vue.d.ts +21 -21
  26. package/dist/client/vue.js +37 -526
  27. package/dist/client/vue.js.map +5 -20
  28. package/dist/credentials/import.d.ts +16 -1
  29. package/dist/credentials/register.d.ts +1 -1
  30. package/dist/credentials/routes.d.ts +1 -1
  31. package/dist/fingerprint-client/index.js +4 -3
  32. package/dist/fingerprint-client/index.js.map +3 -3
  33. package/dist/index.d.ts +3 -3
  34. package/dist/index.js +6416 -262
  35. package/dist/index.js.map +166 -26
  36. package/dist/manifest.js +343 -2674
  37. package/dist/manifest.js.map +57 -31
  38. package/dist/manifest.json +3 -2
  39. package/dist/oidc/clientIdMetadata.d.ts +1 -5
  40. package/dist/oidc/index.js.map +2 -2
  41. package/dist/oidc/vci.d.ts +1 -1
  42. package/dist/routes/callback.d.ts +1 -1
  43. package/dist/server.js +6412 -261
  44. package/dist/server.js.map +166 -26
  45. package/dist/session/neonStore.d.ts +2 -2
  46. package/dist/session/redisStore.d.ts +2 -2
  47. package/dist/session/types.d.ts +2 -0
  48. package/dist/stores/postgres.d.ts +2 -2
  49. package/dist/types.d.ts +2 -1
  50. package/dist/vault/index.js.map +2 -2
  51. package/dist/webauthn.js +27 -1
  52. package/dist/webauthn.js.map +3 -3
  53. package/docs/MIGRATE-FROM-LUCIA.md +19 -2
  54. package/package.json +15 -6
@@ -1,5 +1,5 @@
1
1
  import { type AnyPgDatabase } from '../stores/postgres';
2
- import type { AuditSink } from './types';
2
+ import { type AuditSink } from './types';
3
3
  export declare const auditEventsTable: import("drizzle-orm/pg-core").PgTableWithColumns<{
4
4
  name: "auth_audit_events";
5
5
  schema: undefined;
@@ -1,5 +1,7 @@
1
1
  import type { OrganizationId } from '../tenancy';
2
2
  export type AuditEventType = 'account_deleted' | 'agent_credential_issued' | 'agent_delegated' | 'agent_registered' | 'agent_revoked' | 'authorization_denied' | 'credentials_login' | 'credentials_login_failed' | 'data_exported' | 'email_verified' | 'identity_conflict' | 'impersonation_ended' | 'impersonation_started' | 'invitation_accepted' | 'invitation_created' | 'logout' | 'membership_removed' | 'mfa_challenge' | 'mfa_challenge_failed' | 'mfa_enrolled' | 'oauth_login' | 'organization_created' | 'password_reset' | 'passwordless_login' | 'register' | 'role_assigned' | 'scim_provision' | 'scim_token_created' | 'session_revoked' | 'setup_session_created' | 'sso_connection_configured' | 'sso_login' | 'token_refreshed' | 'token_revoked' | 'webauthn_authenticated' | 'webauthn_registered';
3
+ export declare const AUDIT_EVENT_TYPES: readonly AuditEventType[];
4
+ export declare const isAuditEventType: (value: string) => value is AuditEventType;
3
5
  export type AuditEvent = {
4
6
  at: number;
5
7
  ip?: string;
@@ -1,8 +1,10 @@
1
1
  import type { CredentialsConfig } from '../credentials/config';
2
2
  import type { MfaConfig } from '../mfa/config';
3
- import type { OnCallbackSuccess, OnRevocationSuccess, OnSignOut } from '../types';
3
+ import type { OnRevocationSuccess, OnSignOut } from '../types';
4
4
  import type { AuditEmitter } from './config';
5
- export declare const composeCallbackAudit: <UserType>(onCallbackSuccess: OnCallbackSuccess<UserType>, emit: AuditEmitter) => (context: Parameters<NonNullable<OnCallbackSuccess<UserType>>>[0]) => Promise<void | Response | import("..").StatusReturn>;
5
+ export declare const composeCallbackAudit: <Context extends {
6
+ authProvider: string;
7
+ }, Result>(onCallbackSuccess: ((context: Context) => Promise<Result> | Result) | undefined, emit: AuditEmitter) => (context: Context) => Promise<Result | undefined>;
6
8
  export declare const composeCredentialsAudit: <UserType>(credentials: CredentialsConfig<UserType>, emit: AuditEmitter, getUserId?: (user: UserType) => string) => CredentialsConfig<UserType>;
7
9
  export declare const composeMfaAudit: <UserType>(mfa: MfaConfig<UserType>, emit: AuditEmitter) => MfaConfig<UserType>;
8
10
  export declare const composeRevocationAudit: (onRevocationSuccess: OnRevocationSuccess, emit: AuditEmitter) => (context: Parameters<NonNullable<OnRevocationSuccess>>[0]) => Promise<void | undefined>;
@@ -1,2 +1,2 @@
1
- import type { Importer } from './types';
1
+ import { type Importer } from './types';
2
2
  export declare const auth0Importer: Importer;
@@ -1,2 +1,2 @@
1
- import type { Importer } from './types';
1
+ import { type Importer } from './types';
2
2
  export declare const clerkImporter: Importer;
@@ -1,2 +1,2 @@
1
- import type { Importer } from './types';
1
+ import { type Importer } from './types';
2
2
  export declare const luciaImporter: Importer;
@@ -1,2 +1,2 @@
1
- import type { Importer } from './types';
1
+ import { type Importer } from './types';
2
2
  export declare const nextauthImporter: Importer;
@@ -1,3 +1,4 @@
1
+ export declare const detectPasswordHashAlgorithm: (hash?: string) => ImportedUser['passwordHashAlgo'];
1
2
  export type ImportedUser = {
2
3
  createdAtMs: number;
3
4
  email: string;
@@ -6,13 +6,34 @@ import { neon } from "@neondatabase/serverless";
6
6
 
7
7
  // src/cli/import/auth0.ts
8
8
  import { readFile } from "fs/promises";
9
+
10
+ // src/cli/import/types.ts
11
+ var detectPasswordHashAlgorithm = (hash) => {
12
+ if (hash?.startsWith("$argon2id"))
13
+ return "argon2id";
14
+ if (hash?.startsWith("$2b$") || hash?.startsWith("$2a$") || hash?.startsWith("$2y$") || hash?.startsWith("$2"))
15
+ return "bcrypt";
16
+ return;
17
+ };
18
+
19
+ // src/cli/import/auth0.ts
20
+ var isAuth0Identity = (value) => typeof value === "object" && value !== null && typeof Reflect.get(value, "provider") === "string" && typeof Reflect.get(value, "user_id") === "string";
21
+ var isAuth0User = (value) => typeof value === "object" && value !== null && typeof Reflect.get(value, "email") === "string" && typeof Reflect.get(value, "user_id") === "string" && (Reflect.get(value, "identities") === undefined || Array.isArray(Reflect.get(value, "identities")) && Reflect.get(value, "identities").every(isAuth0Identity));
22
+ var requireAuth0User = (value) => {
23
+ if (!isAuth0User(value))
24
+ throw new Error("Invalid Auth0 user export record");
25
+ return value;
26
+ };
9
27
  var parseUsersFromText = (text) => {
10
28
  const trimmed = text.trim();
11
29
  if (trimmed.startsWith("[")) {
12
- return JSON.parse(trimmed);
30
+ const parsed = JSON.parse(trimmed);
31
+ if (!Array.isArray(parsed))
32
+ throw new Error("Auth0 JSON export must be an array");
33
+ return parsed.map(requireAuth0User);
13
34
  }
14
35
  return trimmed.split(`
15
- `).filter((line) => line.length > 0).map((line) => JSON.parse(line));
36
+ `).filter((line) => line.length > 0).map((line) => requireAuth0User(JSON.parse(line)));
16
37
  };
17
38
  var auth0Importer = {
18
39
  source: "auth0",
@@ -27,7 +48,7 @@ var auth0Importer = {
27
48
  familyName: raw.family_name,
28
49
  givenName: raw.given_name,
29
50
  passwordHash: raw.password_hash,
30
- passwordHashAlgo: raw.password_hash?.startsWith("$2b$") || raw.password_hash?.startsWith("$2a$") || raw.password_hash?.startsWith("$2y$") ? "bcrypt" : undefined
51
+ passwordHashAlgo: detectPasswordHashAlgorithm(raw.password_hash)
31
52
  }));
32
53
  const identities = auth0Users.flatMap((raw) => (raw.identities ?? []).filter((identity) => identity.provider !== "auth0").map((identity) => ({
33
54
  authProvider: identity.provider.replace("-oauth2", ""),
@@ -49,7 +70,7 @@ var clerkImporter = {
49
70
  const text = await readFile2(path, "utf-8");
50
71
  const clerkUsers = JSON.parse(text);
51
72
  const users = clerkUsers.filter((raw) => raw.email_addresses !== undefined && raw.email_addresses.length > 0).map((raw) => {
52
- const primary = raw.email_addresses?.find((e) => raw.primary_email_address_id === undefined || e.email_address.length > 0) ?? raw.email_addresses?.[0];
73
+ const primary = raw.email_addresses?.find((email) => raw.primary_email_address_id === undefined || email.email_address.length > 0) ?? raw.email_addresses?.[0];
53
74
  return {
54
75
  createdAtMs: raw.created_at ?? Date.now(),
55
76
  email: primary?.email_address ?? "",
@@ -58,7 +79,7 @@ var clerkImporter = {
58
79
  familyName: raw.last_name,
59
80
  givenName: raw.first_name,
60
81
  passwordHash: raw.password_digest,
61
- passwordHashAlgo: raw.password_digest?.startsWith("$argon2id") ? "argon2id" : raw.password_digest?.startsWith("$2") ? "bcrypt" : undefined
82
+ passwordHashAlgo: detectPasswordHashAlgorithm(raw.password_digest)
62
83
  };
63
84
  });
64
85
  const identities = clerkUsers.flatMap((raw) => (raw.external_accounts ?? []).map((account) => ({
@@ -80,6 +101,17 @@ var toMs = (value) => {
80
101
  return value < 1000000000000 ? value * 1000 : value;
81
102
  return Date.parse(value);
82
103
  };
104
+ var classifyLuciaKey = (key, passwordByUserId, oauthKeys) => {
105
+ const separator = key.id.indexOf(":");
106
+ if (separator < 0)
107
+ return;
108
+ const provider = key.id.slice(0, separator);
109
+ if (provider === "email" || provider === "username") {
110
+ passwordByUserId.set(key.user_id, key.hashed_password);
111
+ return;
112
+ }
113
+ oauthKeys.push(key);
114
+ };
83
115
  var luciaImporter = {
84
116
  source: "lucia",
85
117
  parse: async (path) => {
@@ -88,15 +120,7 @@ var luciaImporter = {
88
120
  const passwordByUserId = new Map;
89
121
  const oauthKeys = [];
90
122
  for (const key of parsed.keys ?? []) {
91
- const separator = key.id.indexOf(":");
92
- if (separator < 0)
93
- continue;
94
- const provider = key.id.slice(0, separator);
95
- if (provider === "email" || provider === "username") {
96
- passwordByUserId.set(key.user_id, key.hashed_password);
97
- } else {
98
- oauthKeys.push(key);
99
- }
123
+ classifyLuciaKey(key, passwordByUserId, oauthKeys);
100
124
  }
101
125
  const users = parsed.users.map((raw) => ({
102
126
  createdAtMs: toMs(raw.created_at),
@@ -104,7 +128,7 @@ var luciaImporter = {
104
128
  emailVerified: true,
105
129
  externalId: raw.id,
106
130
  passwordHash: passwordByUserId.get(raw.id),
107
- passwordHashAlgo: passwordByUserId.get(raw.id)?.startsWith("$argon2id") ? "argon2id" : passwordByUserId.get(raw.id)?.startsWith("$2") ? "bcrypt" : undefined
131
+ passwordHashAlgo: detectPasswordHashAlgorithm(passwordByUserId.get(raw.id))
108
132
  }));
109
133
  const identities = oauthKeys.map((key) => {
110
134
  const separator = key.id.indexOf(":");
@@ -148,7 +172,7 @@ var nextauthImporter = {
148
172
  familyName: split.familyName,
149
173
  givenName: split.givenName,
150
174
  passwordHash,
151
- passwordHashAlgo: passwordHash?.startsWith("$argon2id") ? "argon2id" : passwordHash?.startsWith("$2") ? "bcrypt" : undefined
175
+ passwordHashAlgo: detectPasswordHashAlgorithm(passwordHash)
152
176
  };
153
177
  });
154
178
  const identities = (parsed.accounts ?? []).filter((account) => account.type === undefined || account.type === "oauth").map((account) => ({
@@ -340,7 +364,7 @@ var apiKeysTable = pgTable2("auth_api_keys", {
340
364
  });
341
365
 
342
366
  // src/agents/postgresStores.ts
343
- import { and as and2, desc as desc3, eq as eq3, gt, isNull, or, sql } from "drizzle-orm";
367
+ import { and as and2, desc as desc3, eq as eq3, gt, isNull, or } from "drizzle-orm";
344
368
  import {
345
369
  bigint as bigint3,
346
370
  customType,
@@ -3074,19 +3098,20 @@ var JOURNAL_DDL = `CREATE TABLE IF NOT EXISTS "auth_migrations" (
3074
3098
  "applied_at_ms" bigint NOT NULL
3075
3099
  );`;
3076
3100
  var isJournalRow = (value) => typeof value === "object" && value !== null && typeof Reflect.get(value, "id") === "string";
3077
- var allBlockNames = () => Object.keys(blockMigrations);
3078
- var applyOne = async (pool, id, sql2, log) => {
3079
- await pool.query(sql2);
3101
+ var isBlockName = (value) => Object.hasOwn(blockMigrations, value);
3102
+ var allBlockNames = () => Object.keys(blockMigrations).filter(isBlockName);
3103
+ var applyOne = async (pool, id, sql, log) => {
3104
+ await pool.query(sql);
3080
3105
  await pool.query(`INSERT INTO "auth_migrations" ("id", "applied_at_ms") VALUES ($1, $2)`, [id, Date.now()]);
3081
3106
  log(`apply ${id}`);
3082
3107
  };
3083
- var runOne = async (pool, id, sql2, applied, result, log) => {
3108
+ var runOne = async (pool, id, sql, applied, result, log) => {
3084
3109
  if (applied.has(id)) {
3085
3110
  result.skipped.push(id);
3086
3111
  log(`skip ${id}`);
3087
3112
  return;
3088
3113
  }
3089
- await applyOne(pool, id, sql2, log);
3114
+ await applyOne(pool, id, sql, log);
3090
3115
  result.applied.push(id);
3091
3116
  };
3092
3117
  var runMigrations = async ({
@@ -3260,6 +3285,21 @@ Options:
3260
3285
  --commit Without this, the run is a dry-run (counts only, no inserts)
3261
3286
  --help Print this message
3262
3287
  `;
3288
+ var isBlockName2 = (value) => Object.hasOwn(blockMigrations, value);
3289
+ var applyMigrateFlag = (parsed, args, flag) => {
3290
+ if (flag === "--help" || flag === "-h") {
3291
+ parsed.help = true;
3292
+ return;
3293
+ }
3294
+ if (flag === "--db" || flag === "--database-url") {
3295
+ parsed.databaseUrl = args.shift();
3296
+ return;
3297
+ }
3298
+ if (flag !== "--blocks")
3299
+ return;
3300
+ const list = args.shift() ?? "";
3301
+ parsed.blocks = list.split(",").map((entry) => entry.trim()).filter((entry) => entry.length > 0);
3302
+ };
3263
3303
  var parseMigrateArgs = (argv) => {
3264
3304
  const parsed = {
3265
3305
  blocks: undefined,
@@ -3268,18 +3308,28 @@ var parseMigrateArgs = (argv) => {
3268
3308
  };
3269
3309
  const args = [...argv];
3270
3310
  while (args.length > 0) {
3271
- const flag = args.shift();
3272
- if (flag === "--help" || flag === "-h") {
3273
- parsed.help = true;
3274
- } else if (flag === "--db" || flag === "--database-url") {
3275
- parsed.databaseUrl = args.shift();
3276
- } else if (flag === "--blocks") {
3277
- const list = args.shift() ?? "";
3278
- parsed.blocks = list.split(",").map((entry) => entry.trim()).filter((entry) => entry.length > 0).map((entry) => entry);
3279
- }
3311
+ applyMigrateFlag(parsed, args, args.shift());
3280
3312
  }
3281
3313
  return parsed;
3282
3314
  };
3315
+ var applyImportArgument = (parsed, args, positionals, next) => {
3316
+ if (next === undefined)
3317
+ return;
3318
+ if (next === "--help" || next === "-h") {
3319
+ parsed.help = true;
3320
+ return;
3321
+ }
3322
+ if (next === "--db" || next === "--database-url") {
3323
+ parsed.databaseUrl = args.shift();
3324
+ return;
3325
+ }
3326
+ if (next === "--commit") {
3327
+ parsed.commit = true;
3328
+ return;
3329
+ }
3330
+ if (!next.startsWith("--"))
3331
+ positionals.push(next);
3332
+ };
3283
3333
  var parseImportArgs = (argv) => {
3284
3334
  const parsed = {
3285
3335
  commit: false,
@@ -3291,21 +3341,11 @@ var parseImportArgs = (argv) => {
3291
3341
  const args = [...argv];
3292
3342
  const positionals = [];
3293
3343
  while (args.length > 0) {
3294
- const next = args.shift();
3295
- if (next === undefined)
3296
- break;
3297
- if (next === "--help" || next === "-h") {
3298
- parsed.help = true;
3299
- } else if (next === "--db" || next === "--database-url") {
3300
- parsed.databaseUrl = args.shift();
3301
- } else if (next === "--commit") {
3302
- parsed.commit = true;
3303
- } else if (!next.startsWith("--")) {
3304
- positionals.push(next);
3305
- }
3344
+ applyImportArgument(parsed, args, positionals, args.shift());
3306
3345
  }
3307
- parsed.source = positionals[0];
3308
- parsed.file = positionals[1];
3346
+ const [source, file] = positionals;
3347
+ parsed.source = source;
3348
+ parsed.file = file;
3309
3349
  return parsed;
3310
3350
  };
3311
3351
  var die = (message, usage) => {
@@ -3331,7 +3371,11 @@ var runMigrate = async (argv) => {
3331
3371
  die(`unknown block(s): ${unknown.join(", ")}`, MIGRATE_USAGE);
3332
3372
  return;
3333
3373
  }
3334
- const result = await runMigrations({ blocks, databaseUrl: resolved });
3374
+ const selectedBlocks = blocks?.filter(isBlockName2);
3375
+ const result = await runMigrations({
3376
+ blocks: selectedBlocks,
3377
+ databaseUrl: resolved
3378
+ });
3335
3379
  process.stdout.write(`
3336
3380
  ${result.applied.length} migration(s) applied, ${result.skipped.length} skipped.
3337
3381
  `);
@@ -3393,5 +3437,5 @@ var main = async () => {
3393
3437
  };
3394
3438
  await main();
3395
3439
 
3396
- //# debugId=65D4841F833D75BF64756E2164756E21
3440
+ //# debugId=F5FC77C8DEF0189164756E2164756E21
3397
3441
  //# sourceMappingURL=migrate.js.map