@holo-js/auth-clerk 0.2.6 → 0.3.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.
package/dist/index.d.ts CHANGED
@@ -1,5 +1,4 @@
1
- import { AuthResult, AuthenticatedAuthUser, AuthEstablishedSession, AuthFieldErrors, AuthLogoutResult, authRuntimeInternals } from '@holo-js/auth';
2
- import { AuthClerkProviderConfig, NormalizedAuthClerkProviderConfig } from '@holo-js/config';
1
+ import { AuthClerkProviderConfig, AuthResult, AuthenticatedAuthUser, AuthEstablishedSession, AuthFieldErrors, AuthLogoutResult, NormalizedAuthClerkProviderConfig, authRuntimeInternals } from '@holo-js/auth';
3
2
 
4
3
  interface ClerkEmailAddress {
5
4
  readonly id?: string;
package/dist/index.mjs CHANGED
@@ -114,6 +114,7 @@ async function verifyClerkSessionToken(token, config, authorizedParties = []) {
114
114
  if ((typeof parsed.payload.sid !== "string" || !parsed.payload.sid.trim()) && (typeof parsed.payload.session_id !== "string" || !parsed.payload.session_id.trim())) {
115
115
  throw new Error("[@holo-js/auth-clerk] Clerk token did not include a session id.");
116
116
  }
117
+ const sessionId = typeof parsed.payload.sid === "string" && parsed.payload.sid.trim() ? parsed.payload.sid.trim() : parsed.payload.session_id.trim();
117
118
  const nbf = typeof parsed.payload.nbf === "number" ? parsed.payload.nbf : void 0;
118
119
  if (typeof nbf === "number" && nbf * 1e3 > Date.now()) {
119
120
  throw new Error("[@holo-js/auth-clerk] Clerk token is not valid yet.");
@@ -126,7 +127,12 @@ async function verifyClerkSessionToken(token, config, authorizedParties = []) {
126
127
  if (azp && allowedAuthorizedParties.length > 0 && !allowedAuthorizedParties.includes(azp)) {
127
128
  throw new Error(`[@holo-js/auth-clerk] Clerk token authorized party "${azp}" is not allowed.`);
128
129
  }
129
- return parsed.payload;
130
+ return Object.freeze({
131
+ ...parsed.payload,
132
+ exp,
133
+ sessionId,
134
+ sub: parsed.payload.sub.trim()
135
+ });
130
136
  }
131
137
  function normalizeClerkEmailAddress(value) {
132
138
  const verification = value.verification && typeof value.verification === "object" ? value.verification : void 0;
@@ -181,7 +187,7 @@ function createDefaultProviderRuntime(providerName, config) {
181
187
  config.apiUrl ?? "",
182
188
  config.frontendApi ?? "",
183
189
  config.secretKey ?? "",
184
- [...config.authorizedParties ?? []].sort()
190
+ [...config.authorizedParties].sort()
185
191
  ]);
186
192
  const existing = clerkDefaultProviderRuntimeCache.get(cacheKey);
187
193
  if (existing) {
@@ -190,14 +196,9 @@ function createDefaultProviderRuntime(providerName, config) {
190
196
  const runtime = Object.freeze({
191
197
  async verifySession({ token }) {
192
198
  const claims = await verifyClerkSessionToken(token, config, config.authorizedParties);
193
- const userId = typeof claims.sub === "string" ? claims.sub : "";
194
- if (!userId) {
195
- throw new Error("[@holo-js/auth-clerk] Clerk token did not include a subject.");
196
- }
197
- const profile = await fetchClerkUserProfile(userId, config);
198
- const sessionId = typeof claims.sid === "string" ? claims.sid : typeof claims.session_id === "string" ? claims.session_id : token;
199
+ const profile = await fetchClerkUserProfile(claims.sub, config);
199
200
  return Object.freeze({
200
- sessionId,
201
+ sessionId: claims.sessionId,
201
202
  user: profile,
202
203
  accessToken: token,
203
204
  raw: Object.freeze({
@@ -219,7 +220,7 @@ function resolveConfiguredProviderName(provider) {
219
220
  if (configuredDefaultProvider) {
220
221
  return configuredDefaultProvider;
221
222
  }
222
- const configuredProviders = Object.entries(bindings.config.clerk).flatMap(([name, value]) => name !== "provider" && name !== "identityStore" && isNormalizedClerkProviderConfig(value) ? [name] : []);
223
+ const configuredProviders = Object.entries(bindings.config.clerk).flatMap(([name]) => name !== "provider" && name !== "identityStore" ? [name] : []);
223
224
  if (configuredProviders.length === 0) {
224
225
  return "default";
225
226
  }
@@ -249,7 +250,7 @@ function getConfiguredProviderConfig(provider) {
249
250
  frontendApi: configured.frontendApi,
250
251
  redirectUri: configured.redirectUri,
251
252
  sessionCookie: configured.sessionCookie,
252
- authorizedParties: configured.authorizedParties ?? [],
253
+ authorizedParties: configured.authorizedParties,
253
254
  guard: configured.guard,
254
255
  mapToProvider: configured.mapToProvider
255
256
  };
@@ -322,7 +323,7 @@ function createClerkErrorResponse(error, code) {
322
323
  code,
323
324
  message: getErrorMessage(error)
324
325
  }, {
325
- status: error instanceof ClerkAuthConflictError ? 409 : 422
326
+ status: 422
326
327
  });
327
328
  }
328
329
  function resolveGuardAndProvider(provider) {
@@ -330,9 +331,6 @@ function resolveGuardAndProvider(provider) {
330
331
  const providerConfig = getConfiguredProviderConfig(provider);
331
332
  const guardName = providerConfig.guard ?? authBindings.config.defaults.guard;
332
333
  const guard = authBindings.config.guards[guardName];
333
- if (!guard) {
334
- throw new Error(`[@holo-js/auth-clerk] Guard "${guardName}" is not configured for Clerk provider "${providerConfig.name}".`);
335
- }
336
334
  if (guard.driver !== "session") {
337
335
  throw new Error(`[@holo-js/auth-clerk] Clerk sign-in requires auth guard "${guardName}" to use the session driver.`);
338
336
  }
@@ -348,9 +346,6 @@ function resolveGuardAndProvider(provider) {
348
346
  };
349
347
  }
350
348
  function requireUserId(adapter, user, message) {
351
- if (!user || typeof user !== "object") {
352
- throw new Error(message);
353
- }
354
349
  const userId = adapter.getId(user);
355
350
  if (typeof userId !== "string" && typeof userId !== "number") {
356
351
  throw new Error(message);
@@ -363,17 +358,8 @@ function requireUserRecord(user, message) {
363
358
  }
364
359
  return user;
365
360
  }
366
- function requireSerializedUser(user, message) {
367
- if (typeof user.id === "string" || typeof user.id === "number") {
368
- return user;
369
- }
370
- throw new Error(message);
371
- }
372
361
  function createClerkSessionPayload(authenticated, session) {
373
- const user = requireSerializedUser(
374
- authenticated.user,
375
- "[@holo-js/auth-clerk] Clerk-authenticated local users must expose a serializable id."
376
- );
362
+ const user = authenticated.user;
377
363
  return Object.freeze({
378
364
  guard: authenticated.guard,
379
365
  provider: authenticated.authProvider,
@@ -416,7 +402,7 @@ function serializeLocalUser(adapter, user, providerName) {
416
402
  configurable: true
417
403
  });
418
404
  Object.defineProperty(result, "can", {
419
- value: () => false,
405
+ value: async () => false,
420
406
  enumerable: false,
421
407
  configurable: true
422
408
  });
@@ -499,9 +485,6 @@ function normalizeHostedProfile(profile) {
499
485
  });
500
486
  }
501
487
  async function findUserByEmail(adapter, email) {
502
- if (!email?.trim()) {
503
- return null;
504
- }
505
488
  const user = await adapter.findByCredentials({ email: email.trim() });
506
489
  return user ? requireUserRecord(user, "[@holo-js/auth-clerk] Auth provider lookups must return object users.") : null;
507
490
  }
@@ -572,11 +555,11 @@ function createIdentityRecord(input) {
572
555
  }
573
556
  async function withIdentitySyncLock(key, callback) {
574
557
  const previous = clerkIdentitySyncLocks.get(key) ?? Promise.resolve();
575
- let release = () => {
576
- };
577
- const current = previous.then(() => new Promise((resolve) => {
558
+ let release;
559
+ const gate = new Promise((resolve) => {
578
560
  release = resolve;
579
- }));
561
+ });
562
+ const current = previous.then(() => gate);
580
563
  clerkIdentitySyncLocks.set(key, current);
581
564
  await previous;
582
565
  try {
@@ -606,7 +589,7 @@ async function resolveClaimedIdentityUser(adapter, identity, fallback) {
606
589
  await adapter.findById(identity.userId),
607
590
  "[@holo-js/auth-clerk] Claimed Clerk identities must reference an existing local user."
608
591
  );
609
- if (fallback.deleteOnMismatch && adapter.delete) {
592
+ if (adapter.delete) {
610
593
  await adapter.delete(fallback.userId);
611
594
  }
612
595
  return claimedUser;
@@ -640,13 +623,9 @@ function isConfiguredClerkRedirectRequest(request, config) {
640
623
  if (!redirectUri) {
641
624
  return hasClerkCallbackState(request);
642
625
  }
643
- try {
644
- const requestUrl = new URL(request.url);
645
- const configuredUrl = new URL(redirectUri, requestUrl.origin);
646
- return requestUrl.origin === configuredUrl.origin && requestUrl.pathname === configuredUrl.pathname;
647
- } catch {
648
- return false;
649
- }
626
+ const requestUrl = new URL(request.url);
627
+ const configuredUrl = new URL(redirectUri, requestUrl.origin);
628
+ return requestUrl.origin === configuredUrl.origin && requestUrl.pathname === configuredUrl.pathname;
650
629
  }
651
630
  function splitSetCookieHeader(value) {
652
631
  return value.split(/,(?=\s*[^;,=\s]+=)/g).map((cookie) => cookie.trim()).filter(Boolean);
@@ -721,7 +700,7 @@ async function verifySession(token, provider) {
721
700
  function resolveRequestAuthorizedParties(config, request) {
722
701
  return Object.freeze([
723
702
  .../* @__PURE__ */ new Set([
724
- ...config.authorizedParties ?? [],
703
+ ...config.authorizedParties,
725
704
  new URL(request.url).origin
726
705
  ])
727
706
  ]);
@@ -732,9 +711,6 @@ async function verifyDefaultSessionToken(token, providerConfig, authorizedPartie
732
711
  authorizedParties
733
712
  };
734
713
  const defaultRuntime = createDefaultProviderRuntime(providerConfig.name, config);
735
- if (!defaultRuntime.verifySession) {
736
- throw new Error(`[@holo-js/auth-clerk] Clerk provider runtime "${providerConfig.name}" does not implement verifySession().`);
737
- }
738
714
  return defaultRuntime.verifySession({
739
715
  provider: providerConfig.name,
740
716
  token,
@@ -932,8 +908,7 @@ async function syncIdentity(session, provider, options = {}) {
932
908
  const claimedIdentity = await claimNewIdentity(identityStore, identity);
933
909
  const claimedUser = await resolveClaimedIdentityUser(adapter, claimedIdentity, {
934
910
  user: localUser,
935
- userId: identity.userId,
936
- deleteOnMismatch: true
911
+ userId: identity.userId
937
912
  });
938
913
  const claimedStatus = sameUserId(claimedIdentity.userId, identity.userId) ? "created" : "linked";
939
914
  return Object.freeze({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@holo-js/auth-clerk",
3
- "version": "0.2.6",
3
+ "version": "0.3.0",
4
4
  "description": "Holo-JS Framework - Clerk auth integration contracts",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -24,9 +24,8 @@
24
24
  },
25
25
  "dependencies": {
26
26
  "@clerk/backend": "^3.4.7",
27
- "@holo-js/auth": "^0.2.6",
28
- "@holo-js/config": "^0.2.6",
29
- "@holo-js/session": "^0.2.6"
27
+ "@holo-js/auth": "^0.3.0",
28
+ "@holo-js/session": "^0.3.0"
30
29
  },
31
30
  "devDependencies": {
32
31
  "@types/node": "^22.10.2",