@absolutejs/auth 0.79.0 → 0.80.1
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/CHANGELOG.md +16 -0
- package/README.md +34 -0
- package/changelog.json +27 -0
- package/dist/cli/migrate.js +46 -1
- package/dist/cli/migrate.js.map +6 -5
- package/dist/cli/setup.d.ts +12 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +62 -14
- package/dist/index.js.map +8 -7
- package/dist/linkedProviders/credentialError.d.ts +7 -0
- package/dist/linkedProviders/index.d.ts +1 -0
- package/dist/linkedProviders/index.js +57 -10
- package/dist/linkedProviders/index.js.map +6 -5
- package/dist/manifest.js +13 -17
- package/dist/manifest.js.map +3 -3
- package/dist/manifest.json +9 -14
- package/dist/server.js +61 -14
- package/dist/server.js.map +8 -7
- package/dist/session/neonStore.d.ts +4 -0
- package/docs/PERSISTENT-CREDENTIALS.md +103 -0
- package/package.json +1 -1
package/dist/manifest.json
CHANGED
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
}
|
|
48
48
|
]
|
|
49
49
|
},
|
|
50
|
-
"title": "
|
|
50
|
+
"title": "Neon Postgres (persistent sessions)",
|
|
51
51
|
"wiring": {
|
|
52
52
|
"code": "createNeonAuthSessionStore(${env.DATABASE_URL} ?? \"\", decodeSessionUserRecord)",
|
|
53
53
|
"imports": [
|
|
@@ -81,19 +81,19 @@
|
|
|
81
81
|
],
|
|
82
82
|
"lifecycle": [
|
|
83
83
|
{
|
|
84
|
-
"command": "bunx absolute-auth
|
|
84
|
+
"command": "bunx absolute-auth setup",
|
|
85
85
|
"id": "migrate",
|
|
86
86
|
"idempotent": true,
|
|
87
87
|
"kind": "migration",
|
|
88
|
-
"title": "Set up the sign-in
|
|
88
|
+
"title": "Set up the selected sign-in storage",
|
|
89
89
|
"when": "after-install"
|
|
90
90
|
},
|
|
91
91
|
{
|
|
92
|
-
"command": "bunx absolute-auth
|
|
92
|
+
"command": "bunx absolute-auth setup",
|
|
93
93
|
"id": "migrate-upgrade",
|
|
94
94
|
"idempotent": true,
|
|
95
95
|
"kind": "migration",
|
|
96
|
-
"title": "
|
|
96
|
+
"title": "Upgrade the selected sign-in storage",
|
|
97
97
|
"when": "after-upgrade"
|
|
98
98
|
}
|
|
99
99
|
],
|
|
@@ -111,12 +111,6 @@
|
|
|
111
111
|
],
|
|
112
112
|
"requires": {
|
|
113
113
|
"env": [
|
|
114
|
-
{
|
|
115
|
-
"description": "Postgres connection string (sign-in tables live here)",
|
|
116
|
-
"example": "postgres://user:pass@host/db",
|
|
117
|
-
"key": "DATABASE_URL",
|
|
118
|
-
"secret": true
|
|
119
|
-
},
|
|
120
114
|
{
|
|
121
115
|
"description": "Absolutejs OAuth client id",
|
|
122
116
|
"docsUrl": "https://absolutejs.ai/dashboard",
|
|
@@ -258,7 +252,8 @@
|
|
|
258
252
|
"services": [
|
|
259
253
|
{
|
|
260
254
|
"description": "Stores accounts, sessions, and audit events",
|
|
261
|
-
"id": "postgres"
|
|
255
|
+
"id": "postgres",
|
|
256
|
+
"optional": true
|
|
262
257
|
}
|
|
263
258
|
]
|
|
264
259
|
},
|
|
@@ -321,8 +316,8 @@
|
|
|
321
316
|
"contract": "auth/session-store",
|
|
322
317
|
"description": "Where live sign-in sessions are kept",
|
|
323
318
|
"known": [
|
|
324
|
-
"@absolutejs/auth#
|
|
325
|
-
"@absolutejs/auth#
|
|
319
|
+
"@absolutejs/auth#createNeonAuthSessionStore",
|
|
320
|
+
"@absolutejs/auth#createInMemoryAuthSessionStore"
|
|
326
321
|
],
|
|
327
322
|
"required": true
|
|
328
323
|
},
|
package/dist/server.js
CHANGED
|
@@ -26789,10 +26789,9 @@ var toUnregisteredSessionData = (row) => ({
|
|
|
26789
26789
|
sessionInformation: cloneRecord(row.session_information_json ?? undefined),
|
|
26790
26790
|
userIdentity: cloneRecord(row.user_identity_json ?? undefined)
|
|
26791
26791
|
});
|
|
26792
|
-
var createNeonAuthSessionStore = (databaseUrl, decodeUser) => {
|
|
26793
|
-
|
|
26794
|
-
const
|
|
26795
|
-
return {
|
|
26792
|
+
var createNeonAuthSessionStore = (databaseUrl, decodeUser) => createPostgresAuthSessionStore(drizzle({ client: as(databaseUrl) }), decodeUser);
|
|
26793
|
+
var createPostgresAuthSessionStore = (db, decodeUser) => {
|
|
26794
|
+
const store = {
|
|
26796
26795
|
deleteExpired: async () => {
|
|
26797
26796
|
const rows = await db.delete(authSessionsTable).where(lt(authSessionsTable.expires_at_ms, Date.now())).returning({ id: authSessionsTable.id });
|
|
26798
26797
|
return rows.length;
|
|
@@ -26870,6 +26869,7 @@ var createNeonAuthSessionStore = (databaseUrl, decodeUser) => {
|
|
|
26870
26869
|
});
|
|
26871
26870
|
}
|
|
26872
26871
|
};
|
|
26872
|
+
return store;
|
|
26873
26873
|
};
|
|
26874
26874
|
// src/providersFromEnv.ts
|
|
26875
26875
|
var envKey = (provider, suffix) => `${provider.replace(/[^a-zA-Z0-9]/g, "_").toUpperCase()}_${suffix}`;
|
|
@@ -34966,6 +34966,30 @@ var createRedisAuthSessionStore = (redis, decodeUser, keyPrefix = "auth:session:
|
|
|
34966
34966
|
}
|
|
34967
34967
|
};
|
|
34968
34968
|
};
|
|
34969
|
+
// src/linkedProviders/credentialError.ts
|
|
34970
|
+
class LinkedProviderCredentialError extends Error {
|
|
34971
|
+
code;
|
|
34972
|
+
recovery;
|
|
34973
|
+
constructor(code, recovery, message, cause) {
|
|
34974
|
+
super(message, { cause });
|
|
34975
|
+
this.code = code;
|
|
34976
|
+
this.recovery = recovery;
|
|
34977
|
+
this.name = "LinkedProviderCredentialError";
|
|
34978
|
+
}
|
|
34979
|
+
}
|
|
34980
|
+
var credentialRefreshError = (error2) => {
|
|
34981
|
+
if (error2 instanceof LinkedProviderCredentialError)
|
|
34982
|
+
return error2;
|
|
34983
|
+
const message = error2 instanceof Error ? error2.message : "";
|
|
34984
|
+
if (/\binvalid_grant\b/.test(message)) {
|
|
34985
|
+
return new LinkedProviderCredentialError("invalid_grant", "reconnect", "Authorization has expired or was revoked. Reconnect your account.", error2);
|
|
34986
|
+
}
|
|
34987
|
+
if (/\b(invalid_client|unauthorized_client)\b/.test(message)) {
|
|
34988
|
+
return new LinkedProviderCredentialError("invalid_client", "configuration", "The provider connection is misconfigured. Contact support.", error2);
|
|
34989
|
+
}
|
|
34990
|
+
return new LinkedProviderCredentialError("refresh_failed", "retry", "The provider could not refresh the connection. Try again.", error2);
|
|
34991
|
+
};
|
|
34992
|
+
|
|
34969
34993
|
// src/linkedProviders/resolver.ts
|
|
34970
34994
|
var uniqueStrings = (values) => [...new Set(values)];
|
|
34971
34995
|
var getEffectiveScopes = (grant, binding) => {
|
|
@@ -35063,6 +35087,30 @@ var resolveBindingCredential = async (grantStore, binding, input) => {
|
|
|
35063
35087
|
}
|
|
35064
35088
|
return buildResolvedCredential(grant, binding);
|
|
35065
35089
|
};
|
|
35090
|
+
var refreshAndRecord = async (grant, input, refresh2, grantStore, now) => {
|
|
35091
|
+
let refreshed;
|
|
35092
|
+
try {
|
|
35093
|
+
const result = await refresh2(grant, input);
|
|
35094
|
+
if (!result)
|
|
35095
|
+
throw new Error("Linked provider access token refresh failed");
|
|
35096
|
+
refreshed = result;
|
|
35097
|
+
} catch (cause) {
|
|
35098
|
+
const error2 = credentialRefreshError(cause);
|
|
35099
|
+
await grantStore.saveGrant({
|
|
35100
|
+
...grant,
|
|
35101
|
+
lastRefreshError: error2.message,
|
|
35102
|
+
metadata: { ...grant.metadata, credentialFailureCode: error2.code, credentialRecovery: error2.recovery },
|
|
35103
|
+
status: "refresh_required",
|
|
35104
|
+
updatedAt: now()
|
|
35105
|
+
});
|
|
35106
|
+
throw error2;
|
|
35107
|
+
}
|
|
35108
|
+
const metadata = { ...refreshed.grant.metadata };
|
|
35109
|
+
delete metadata.credentialRecovery;
|
|
35110
|
+
delete metadata.credentialFailureCode;
|
|
35111
|
+
await grantStore.saveGrant({ ...refreshed.grant, lastRefreshError: undefined, metadata });
|
|
35112
|
+
return refreshed;
|
|
35113
|
+
};
|
|
35066
35114
|
var createLinkedProviderCredentialResolver = ({
|
|
35067
35115
|
grantStore,
|
|
35068
35116
|
bindingStore,
|
|
@@ -35092,11 +35140,7 @@ var createLinkedProviderCredentialResolver = ({
|
|
|
35092
35140
|
if (!refreshAccessTokenLease) {
|
|
35093
35141
|
throw new Error("Linked provider access token lease requires refresh");
|
|
35094
35142
|
}
|
|
35095
|
-
const refreshed = await
|
|
35096
|
-
if (!refreshed) {
|
|
35097
|
-
throw new Error("Linked provider access token refresh failed");
|
|
35098
|
-
}
|
|
35099
|
-
await grantStore.saveGrant(refreshed.grant);
|
|
35143
|
+
const refreshed = await refreshAndRecord(grant, input, refreshAccessTokenLease, grantStore, now);
|
|
35100
35144
|
({ lease } = refreshed);
|
|
35101
35145
|
}
|
|
35102
35146
|
if (!lease) {
|
|
@@ -35189,8 +35233,11 @@ var createOAuthLinkedProviderCredentialResolver = async ({
|
|
|
35189
35233
|
tokenType: grant.tokenType
|
|
35190
35234
|
} : null,
|
|
35191
35235
|
refreshAccessTokenLease: async (grant) => {
|
|
35192
|
-
if (!
|
|
35193
|
-
|
|
35236
|
+
if (!grant.refreshTokenCiphertext) {
|
|
35237
|
+
throw new LinkedProviderCredentialError("missing_refresh_token", "reconnect", "Authorization cannot renew automatically. Reconnect your account.");
|
|
35238
|
+
}
|
|
35239
|
+
if (!isValidProviderOption(grant.authProviderKey)) {
|
|
35240
|
+
throw new LinkedProviderCredentialError("unsupported_provider", "configuration", "This provider cannot renew the connection. Contact support.");
|
|
35194
35241
|
}
|
|
35195
35242
|
const providerKey = grant.authProviderKey;
|
|
35196
35243
|
const providerClientName = typeof grant.metadata?.providerClient === "string" && grant.metadata.providerClient.trim().length > 0 ? grant.metadata.providerClient.trim() : undefined;
|
|
@@ -35200,11 +35247,11 @@ var createOAuthLinkedProviderCredentialResolver = async ({
|
|
|
35200
35247
|
providersConfiguration
|
|
35201
35248
|
});
|
|
35202
35249
|
if ("error" in resolvedProviderClientConfiguration || !resolvedProviderClientConfiguration.config) {
|
|
35203
|
-
|
|
35250
|
+
throw new LinkedProviderCredentialError("provider_configuration", "configuration", "The provider connection is misconfigured. Contact support.");
|
|
35204
35251
|
}
|
|
35205
35252
|
const providerClient = await createOAuth2Client(providerKey, resolvedProviderClientConfiguration.config.credentials);
|
|
35206
35253
|
if (!providerClient || !isRefreshableOAuth2Client(providerKey, providerClient)) {
|
|
35207
|
-
|
|
35254
|
+
throw new LinkedProviderCredentialError("unsupported_refresh", "configuration", "This provider cannot renew the connection. Contact support.");
|
|
35208
35255
|
}
|
|
35209
35256
|
const tokenResponse2 = await providerClient.refreshAccessToken(grant.refreshTokenCiphertext);
|
|
35210
35257
|
const refreshedAt = Date.now();
|
|
@@ -42097,5 +42144,5 @@ export {
|
|
|
42097
42144
|
userSessionIdTypebox
|
|
42098
42145
|
};
|
|
42099
42146
|
|
|
42100
|
-
//# debugId=
|
|
42147
|
+
//# debugId=DE4780E5239C13EA64756E2164756E21
|
|
42101
42148
|
//# sourceMappingURL=server.js.map
|