@absolutejs/auth 0.78.0 → 0.80.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.
@@ -0,0 +1,7 @@
1
+ /** Safe recovery information; raw provider responses stay in the cause. */
2
+ export declare class LinkedProviderCredentialError extends Error {
3
+ readonly code: string;
4
+ readonly recovery: 'reconnect' | 'retry' | 'configuration';
5
+ constructor(code: string, recovery: 'reconnect' | 'retry' | 'configuration', message: string, cause?: unknown);
6
+ }
7
+ export declare const credentialRefreshError: (error: unknown) => LinkedProviderCredentialError;
@@ -1,3 +1,4 @@
1
+ export { LinkedProviderCredentialError } from './credentialError';
1
2
  export { createOAuthAccountLinkedProviderCredentialResolver, type OAuthLinkedProviderAccount, type OAuthLinkedProviderAccountStore } from './oauthAccountResolver';
2
3
  export { createOAuthLinkedProviderCredentialResolver } from './oauthResolver';
3
4
  export { createLinkedProviderCredentialResolver, type CreateLinkedProviderCredentialResolverOptions, type LinkedProviderRefreshResult } from './resolver';
@@ -48,6 +48,29 @@ var __export = (target, all) => {
48
48
  var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
49
49
  var __require = import.meta.require;
50
50
 
51
+ // src/linkedProviders/credentialError.ts
52
+ class LinkedProviderCredentialError extends Error {
53
+ code;
54
+ recovery;
55
+ constructor(code, recovery, message, cause) {
56
+ super(message, { cause });
57
+ this.code = code;
58
+ this.recovery = recovery;
59
+ this.name = "LinkedProviderCredentialError";
60
+ }
61
+ }
62
+ var credentialRefreshError = (error) => {
63
+ if (error instanceof LinkedProviderCredentialError)
64
+ return error;
65
+ const message = error instanceof Error ? error.message : "";
66
+ if (/\binvalid_grant\b/.test(message)) {
67
+ return new LinkedProviderCredentialError("invalid_grant", "reconnect", "Authorization has expired or was revoked. Reconnect your account.", error);
68
+ }
69
+ if (/\b(invalid_client|unauthorized_client)\b/.test(message)) {
70
+ return new LinkedProviderCredentialError("invalid_client", "configuration", "The provider connection is misconfigured. Contact support.", error);
71
+ }
72
+ return new LinkedProviderCredentialError("refresh_failed", "retry", "The provider could not refresh the connection. Try again.", error);
73
+ };
51
74
  // node_modules/citra/dist/index.js
52
75
  var BASE64_BLOCK_SIZE = 4;
53
76
  var NUM_GENERATOR_BYTES = 32;
@@ -3141,6 +3164,30 @@ var resolveBindingCredential = async (grantStore, binding, input) => {
3141
3164
  }
3142
3165
  return buildResolvedCredential(grant, binding);
3143
3166
  };
3167
+ var refreshAndRecord = async (grant, input, refresh, grantStore, now) => {
3168
+ let refreshed;
3169
+ try {
3170
+ const result = await refresh(grant, input);
3171
+ if (!result)
3172
+ throw new Error("Linked provider access token refresh failed");
3173
+ refreshed = result;
3174
+ } catch (cause) {
3175
+ const error = credentialRefreshError(cause);
3176
+ await grantStore.saveGrant({
3177
+ ...grant,
3178
+ lastRefreshError: error.message,
3179
+ metadata: { ...grant.metadata, credentialFailureCode: error.code, credentialRecovery: error.recovery },
3180
+ status: "refresh_required",
3181
+ updatedAt: now()
3182
+ });
3183
+ throw error;
3184
+ }
3185
+ const metadata = { ...refreshed.grant.metadata };
3186
+ delete metadata.credentialRecovery;
3187
+ delete metadata.credentialFailureCode;
3188
+ await grantStore.saveGrant({ ...refreshed.grant, lastRefreshError: undefined, metadata });
3189
+ return refreshed;
3190
+ };
3144
3191
  var createLinkedProviderCredentialResolver = ({
3145
3192
  grantStore,
3146
3193
  bindingStore,
@@ -3170,11 +3217,7 @@ var createLinkedProviderCredentialResolver = ({
3170
3217
  if (!refreshAccessTokenLease) {
3171
3218
  throw new Error("Linked provider access token lease requires refresh");
3172
3219
  }
3173
- const refreshed = await refreshAccessTokenLease(grant, input);
3174
- if (!refreshed) {
3175
- throw new Error("Linked provider access token refresh failed");
3176
- }
3177
- await grantStore.saveGrant(refreshed.grant);
3220
+ const refreshed = await refreshAndRecord(grant, input, refreshAccessTokenLease, grantStore, now);
3178
3221
  ({ lease } = refreshed);
3179
3222
  }
3180
3223
  if (!lease) {
@@ -3268,8 +3311,11 @@ var createOAuthLinkedProviderCredentialResolver = async ({
3268
3311
  tokenType: grant.tokenType
3269
3312
  } : null,
3270
3313
  refreshAccessTokenLease: async (grant) => {
3271
- if (!isValidProviderOption(grant.authProviderKey) || !grant.refreshTokenCiphertext) {
3272
- return null;
3314
+ if (!grant.refreshTokenCiphertext) {
3315
+ throw new LinkedProviderCredentialError("missing_refresh_token", "reconnect", "Authorization cannot renew automatically. Reconnect your account.");
3316
+ }
3317
+ if (!isValidProviderOption(grant.authProviderKey)) {
3318
+ throw new LinkedProviderCredentialError("unsupported_provider", "configuration", "This provider cannot renew the connection. Contact support.");
3273
3319
  }
3274
3320
  const providerKey = grant.authProviderKey;
3275
3321
  const providerClientName = typeof grant.metadata?.providerClient === "string" && grant.metadata.providerClient.trim().length > 0 ? grant.metadata.providerClient.trim() : undefined;
@@ -3279,11 +3325,11 @@ var createOAuthLinkedProviderCredentialResolver = async ({
3279
3325
  providersConfiguration
3280
3326
  });
3281
3327
  if ("error" in resolvedProviderClientConfiguration || !resolvedProviderClientConfiguration.config) {
3282
- return null;
3328
+ throw new LinkedProviderCredentialError("provider_configuration", "configuration", "The provider connection is misconfigured. Contact support.");
3283
3329
  }
3284
3330
  const providerClient = await createOAuth2Client(providerKey, resolvedProviderClientConfiguration.config.credentials);
3285
3331
  if (!providerClient || !isRefreshableOAuth2Client(providerKey, providerClient)) {
3286
- return null;
3332
+ throw new LinkedProviderCredentialError("unsupported_refresh", "configuration", "This provider cannot renew the connection. Contact support.");
3287
3333
  }
3288
3334
  const tokenResponse = await providerClient.refreshAccessToken(grant.refreshTokenCiphertext);
3289
3335
  const refreshedAt = Date.now();
@@ -15387,6 +15433,7 @@ var createInMemoryLinkedProviderStores = (input = {}) => {
15387
15433
  return { bindingStore, grantStore };
15388
15434
  };
15389
15435
  export {
15436
+ LinkedProviderCredentialError,
15390
15437
  createInMemoryLinkedProviderStores,
15391
15438
  createLinkedProviderBindingStore,
15392
15439
  createLinkedProviderCredentialResolver,
@@ -15399,5 +15446,5 @@ export {
15399
15446
  linkedProviderGrantsTable
15400
15447
  };
15401
15448
 
15402
- //# debugId=C2863A61B7F5183B64756E2164756E21
15449
+ //# debugId=0587E5ADD426B10B64756E2164756E21
15403
15450
  //# sourceMappingURL=index.js.map