@absolutejs/auth 0.28.0 → 0.29.0-beta.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 +2 -0
- package/dist/index.js +228 -35
- package/dist/index.js.map +8 -6
- package/dist/webhooks/config.d.ts +14 -1
- package/dist/webhooks/dispatcher.d.ts +1 -1
- package/dist/webhooks/inMemoryStore.d.ts +2 -0
- package/dist/webhooks/postgresStore.d.ts +136 -0
- package/dist/webhooks/types.d.ts +14 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -14892,6 +14892,8 @@ export { createNeonPasswordlessTokenStore, createPostgresPasswordlessTokenStore,
|
|
|
14892
14892
|
export * from './webhooks/config';
|
|
14893
14893
|
export * from './webhooks/types';
|
|
14894
14894
|
export { createWebhookDispatcher } from './webhooks/dispatcher';
|
|
14895
|
+
export { createInMemoryWebhookDeliveryStore } from './webhooks/inMemoryStore';
|
|
14896
|
+
export { createNeonWebhookDeliveryStore, createPostgresWebhookDeliveryStore, webhookDeliveriesTable } from './webhooks/postgresStore';
|
|
14895
14897
|
export { signWebhook, verifyWebhookSignature } from './webhooks/sign';
|
|
14896
14898
|
export * from './portal/config';
|
|
14897
14899
|
export * from './portal/types';
|
package/dist/index.js
CHANGED
|
@@ -7920,6 +7920,14 @@ var webauthnRoutes = ({
|
|
|
7920
7920
|
|
|
7921
7921
|
// src/webhooks/config.ts
|
|
7922
7922
|
var DEFAULT_TIMEOUT_SECONDS = 5;
|
|
7923
|
+
var DEFAULT_RETRY_ATTEMPTS = 3;
|
|
7924
|
+
var DEFAULT_RETRY_INITIAL_DELAY_MS = MILLISECONDS_IN_A_SECOND;
|
|
7925
|
+
var DEFAULT_RETRY_BACKOFF_MULTIPLIER = 2;
|
|
7926
|
+
var DEFAULT_WEBHOOK_RETRY = {
|
|
7927
|
+
attempts: DEFAULT_RETRY_ATTEMPTS,
|
|
7928
|
+
backoffMultiplier: DEFAULT_RETRY_BACKOFF_MULTIPLIER,
|
|
7929
|
+
initialDelayMs: DEFAULT_RETRY_INITIAL_DELAY_MS
|
|
7930
|
+
};
|
|
7923
7931
|
var DEFAULT_WEBHOOK_TIMEOUT_MS = MILLISECONDS_IN_A_SECOND * DEFAULT_TIMEOUT_SECONDS;
|
|
7924
7932
|
|
|
7925
7933
|
// src/webhooks/sign.ts
|
|
@@ -7952,12 +7960,145 @@ var verifyWebhookSignature = async ({
|
|
|
7952
7960
|
};
|
|
7953
7961
|
|
|
7954
7962
|
// src/webhooks/dispatcher.ts
|
|
7963
|
+
var defaultSleep = (delayMs) => new Promise((resolve) => setTimeout(resolve, delayMs));
|
|
7964
|
+
var attemptOnce = async ({
|
|
7965
|
+
envelope,
|
|
7966
|
+
endpoint,
|
|
7967
|
+
fetchImpl,
|
|
7968
|
+
payload,
|
|
7969
|
+
signature,
|
|
7970
|
+
timeoutMs,
|
|
7971
|
+
timestamp
|
|
7972
|
+
}) => {
|
|
7973
|
+
const response = await fetchImpl(endpoint.url, {
|
|
7974
|
+
body: payload,
|
|
7975
|
+
headers: {
|
|
7976
|
+
"content-type": "application/json",
|
|
7977
|
+
"webhook-id": envelope.id,
|
|
7978
|
+
"webhook-signature": signature,
|
|
7979
|
+
"webhook-timestamp": timestamp
|
|
7980
|
+
},
|
|
7981
|
+
method: "POST",
|
|
7982
|
+
signal: AbortSignal.timeout(timeoutMs)
|
|
7983
|
+
});
|
|
7984
|
+
if (!response.ok) {
|
|
7985
|
+
throw new Error(`Webhook delivery returned ${response.status}`);
|
|
7986
|
+
}
|
|
7987
|
+
return response.status;
|
|
7988
|
+
};
|
|
7989
|
+
var errorMessage = (error) => error instanceof Error ? error.message : String(error);
|
|
7990
|
+
var statusFromError = (error) => {
|
|
7991
|
+
if (!(error instanceof Error))
|
|
7992
|
+
return;
|
|
7993
|
+
const match = /returned (\d+)/.exec(error.message);
|
|
7994
|
+
return match?.[1] === undefined ? undefined : Number(match[1]);
|
|
7995
|
+
};
|
|
7996
|
+
var persistFailure = async ({
|
|
7997
|
+
attempts,
|
|
7998
|
+
deliveryStore,
|
|
7999
|
+
endpoint,
|
|
8000
|
+
envelope,
|
|
8001
|
+
lastError
|
|
8002
|
+
}) => {
|
|
8003
|
+
if (deliveryStore === undefined)
|
|
8004
|
+
return;
|
|
8005
|
+
const record = {
|
|
8006
|
+
attempts,
|
|
8007
|
+
createdAt: Date.now(),
|
|
8008
|
+
endpointUrl: endpoint.url,
|
|
8009
|
+
envelope,
|
|
8010
|
+
lastError: errorMessage(lastError),
|
|
8011
|
+
lastStatus: statusFromError(lastError)
|
|
8012
|
+
};
|
|
8013
|
+
await deliveryStore.recordFailure(record);
|
|
8014
|
+
};
|
|
8015
|
+
var tryDeliverThenBackoff = async ({
|
|
8016
|
+
attempt,
|
|
8017
|
+
endpoint,
|
|
8018
|
+
envelope,
|
|
8019
|
+
fetchImpl,
|
|
8020
|
+
payload,
|
|
8021
|
+
retry,
|
|
8022
|
+
signature,
|
|
8023
|
+
sleep,
|
|
8024
|
+
timeoutMs,
|
|
8025
|
+
timestamp
|
|
8026
|
+
}) => {
|
|
8027
|
+
try {
|
|
8028
|
+
await attemptOnce({
|
|
8029
|
+
endpoint,
|
|
8030
|
+
envelope,
|
|
8031
|
+
fetchImpl,
|
|
8032
|
+
payload,
|
|
8033
|
+
signature,
|
|
8034
|
+
timeoutMs,
|
|
8035
|
+
timestamp
|
|
8036
|
+
});
|
|
8037
|
+
return;
|
|
8038
|
+
} catch (error) {
|
|
8039
|
+
const isLastAttempt = attempt >= retry.attempts - 1;
|
|
8040
|
+
await (isLastAttempt ? Promise.resolve() : sleep(retry.initialDelayMs * retry.backoffMultiplier ** attempt));
|
|
8041
|
+
return error;
|
|
8042
|
+
}
|
|
8043
|
+
};
|
|
8044
|
+
var deliverToEndpoint = async ({
|
|
8045
|
+
deliveryStore,
|
|
8046
|
+
endpoint,
|
|
8047
|
+
envelope,
|
|
8048
|
+
fetchImpl,
|
|
8049
|
+
onDeliveryError,
|
|
8050
|
+
payload,
|
|
8051
|
+
retry,
|
|
8052
|
+
signature,
|
|
8053
|
+
sleep,
|
|
8054
|
+
timeoutMs,
|
|
8055
|
+
timestamp
|
|
8056
|
+
}) => {
|
|
8057
|
+
let lastError;
|
|
8058
|
+
for (let attempt = 0;attempt < retry.attempts; attempt++) {
|
|
8059
|
+
const error = await tryDeliverThenBackoff({
|
|
8060
|
+
attempt,
|
|
8061
|
+
endpoint,
|
|
8062
|
+
envelope,
|
|
8063
|
+
fetchImpl,
|
|
8064
|
+
payload,
|
|
8065
|
+
retry,
|
|
8066
|
+
signature,
|
|
8067
|
+
sleep,
|
|
8068
|
+
timeoutMs,
|
|
8069
|
+
timestamp
|
|
8070
|
+
});
|
|
8071
|
+
if (error === undefined)
|
|
8072
|
+
return;
|
|
8073
|
+
lastError = error;
|
|
8074
|
+
}
|
|
8075
|
+
await onDeliveryError?.({
|
|
8076
|
+
endpoint,
|
|
8077
|
+
error: lastError,
|
|
8078
|
+
event: envelope
|
|
8079
|
+
});
|
|
8080
|
+
await persistFailure({
|
|
8081
|
+
attempts: retry.attempts,
|
|
8082
|
+
deliveryStore,
|
|
8083
|
+
endpoint,
|
|
8084
|
+
envelope,
|
|
8085
|
+
lastError
|
|
8086
|
+
});
|
|
8087
|
+
};
|
|
7955
8088
|
var createWebhookDispatcher = ({
|
|
8089
|
+
deliveryStore,
|
|
7956
8090
|
endpoints,
|
|
7957
8091
|
fetch: fetchImpl = globalThis.fetch,
|
|
7958
8092
|
onDeliveryError,
|
|
8093
|
+
retry,
|
|
8094
|
+
sleep = defaultSleep,
|
|
7959
8095
|
timeoutMs = DEFAULT_WEBHOOK_TIMEOUT_MS
|
|
7960
8096
|
}) => {
|
|
8097
|
+
const effectiveRetry = {
|
|
8098
|
+
attempts: retry?.attempts ?? DEFAULT_WEBHOOK_RETRY.attempts,
|
|
8099
|
+
backoffMultiplier: retry?.backoffMultiplier ?? DEFAULT_WEBHOOK_RETRY.backoffMultiplier,
|
|
8100
|
+
initialDelayMs: retry?.initialDelayMs ?? DEFAULT_WEBHOOK_RETRY.initialDelayMs
|
|
8101
|
+
};
|
|
7961
8102
|
const dispatch = async (event) => {
|
|
7962
8103
|
const envelope = {
|
|
7963
8104
|
createdAt: Date.now(),
|
|
@@ -7967,35 +8108,26 @@ var createWebhookDispatcher = ({
|
|
|
7967
8108
|
};
|
|
7968
8109
|
const payload = JSON.stringify(envelope);
|
|
7969
8110
|
const timestamp = Math.floor(Date.now() / MILLISECONDS_IN_A_SECOND).toString();
|
|
7970
|
-
await Promise.all(endpoints.map(async (endpoint) => {
|
|
7971
|
-
|
|
7972
|
-
|
|
7973
|
-
|
|
7974
|
-
|
|
7975
|
-
|
|
7976
|
-
|
|
7977
|
-
|
|
7978
|
-
|
|
7979
|
-
|
|
7980
|
-
|
|
7981
|
-
|
|
7982
|
-
|
|
7983
|
-
|
|
7984
|
-
|
|
7985
|
-
|
|
7986
|
-
|
|
7987
|
-
|
|
7988
|
-
|
|
7989
|
-
|
|
7990
|
-
throw new Error(`Webhook delivery returned ${response.status}`);
|
|
7991
|
-
}
|
|
7992
|
-
} catch (error) {
|
|
7993
|
-
await onDeliveryError?.({
|
|
7994
|
-
endpoint,
|
|
7995
|
-
error,
|
|
7996
|
-
event: envelope
|
|
7997
|
-
});
|
|
7998
|
-
}
|
|
8111
|
+
await Promise.all(endpoints.filter((endpoint) => endpoint.events === undefined || endpoint.events.includes(event.type)).map(async (endpoint) => {
|
|
8112
|
+
const signature = await signWebhook({
|
|
8113
|
+
id: envelope.id,
|
|
8114
|
+
payload,
|
|
8115
|
+
secret: endpoint.secret,
|
|
8116
|
+
timestamp
|
|
8117
|
+
});
|
|
8118
|
+
await deliverToEndpoint({
|
|
8119
|
+
deliveryStore,
|
|
8120
|
+
endpoint,
|
|
8121
|
+
envelope,
|
|
8122
|
+
fetchImpl,
|
|
8123
|
+
onDeliveryError,
|
|
8124
|
+
payload,
|
|
8125
|
+
retry: effectiveRetry,
|
|
8126
|
+
signature,
|
|
8127
|
+
sleep,
|
|
8128
|
+
timeoutMs,
|
|
8129
|
+
timestamp
|
|
8130
|
+
});
|
|
7999
8131
|
}));
|
|
8000
8132
|
};
|
|
8001
8133
|
return dispatch;
|
|
@@ -21318,6 +21450,62 @@ var createPostgresPasswordlessTokenStore = (db) => ({
|
|
|
21318
21450
|
});
|
|
21319
21451
|
}
|
|
21320
21452
|
});
|
|
21453
|
+
// src/webhooks/inMemoryStore.ts
|
|
21454
|
+
var DEFAULT_LIST_LIMIT = 100;
|
|
21455
|
+
var createInMemoryWebhookDeliveryStore = () => {
|
|
21456
|
+
const failures = new Map;
|
|
21457
|
+
return {
|
|
21458
|
+
listFailed: async (limit = DEFAULT_LIST_LIMIT) => Array.from(failures.values()).sort((left, right) => right.createdAt - left.createdAt).slice(0, limit),
|
|
21459
|
+
recordFailure: async (delivery) => {
|
|
21460
|
+
failures.set(delivery.envelope.id, delivery);
|
|
21461
|
+
},
|
|
21462
|
+
removeFailure: async (envelopeId) => {
|
|
21463
|
+
failures.delete(envelopeId);
|
|
21464
|
+
}
|
|
21465
|
+
};
|
|
21466
|
+
};
|
|
21467
|
+
// src/webhooks/postgresStore.ts
|
|
21468
|
+
var ID_LENGTH15 = 255;
|
|
21469
|
+
var URL_LENGTH = 2048;
|
|
21470
|
+
var DEFAULT_LIST_LIMIT2 = 100;
|
|
21471
|
+
var webhookDeliveriesTable = pgTable("auth_webhook_deliveries", {
|
|
21472
|
+
attempts: bigint("attempts", { mode: "number" }).notNull(),
|
|
21473
|
+
created_at_ms: bigint("created_at_ms", { mode: "number" }).notNull(),
|
|
21474
|
+
endpoint_url: varchar("endpoint_url", { length: URL_LENGTH }).notNull(),
|
|
21475
|
+
envelope_id: varchar("envelope_id", { length: ID_LENGTH15 }).primaryKey(),
|
|
21476
|
+
envelope_json: jsonb("envelope_json").$type().notNull(),
|
|
21477
|
+
last_error: text("last_error"),
|
|
21478
|
+
last_status: bigint("last_status", { mode: "number" })
|
|
21479
|
+
});
|
|
21480
|
+
var toDelivery = (row) => ({
|
|
21481
|
+
attempts: row.attempts,
|
|
21482
|
+
createdAt: row.created_at_ms,
|
|
21483
|
+
endpointUrl: row.endpoint_url,
|
|
21484
|
+
envelope: row.envelope_json,
|
|
21485
|
+
lastError: row.last_error ?? undefined,
|
|
21486
|
+
lastStatus: row.last_status ?? undefined
|
|
21487
|
+
});
|
|
21488
|
+
var createNeonWebhookDeliveryStore = (databaseUrl) => createPostgresWebhookDeliveryStore(createNeonDatabase(databaseUrl));
|
|
21489
|
+
var createPostgresWebhookDeliveryStore = (db) => ({
|
|
21490
|
+
listFailed: async (limit = DEFAULT_LIST_LIMIT2) => {
|
|
21491
|
+
const rows = await db.select().from(webhookDeliveriesTable).orderBy(desc(webhookDeliveriesTable.created_at_ms)).limit(limit);
|
|
21492
|
+
return rows.map(toDelivery);
|
|
21493
|
+
},
|
|
21494
|
+
recordFailure: async (delivery) => {
|
|
21495
|
+
await db.insert(webhookDeliveriesTable).values({
|
|
21496
|
+
attempts: delivery.attempts,
|
|
21497
|
+
created_at_ms: delivery.createdAt,
|
|
21498
|
+
endpoint_url: delivery.endpointUrl,
|
|
21499
|
+
envelope_id: delivery.envelope.id,
|
|
21500
|
+
envelope_json: delivery.envelope,
|
|
21501
|
+
last_error: delivery.lastError ?? null,
|
|
21502
|
+
last_status: delivery.lastStatus ?? null
|
|
21503
|
+
});
|
|
21504
|
+
},
|
|
21505
|
+
removeFailure: async (envelopeId) => {
|
|
21506
|
+
await db.delete(webhookDeliveriesTable).where(eq(webhookDeliveriesTable.envelope_id, envelopeId));
|
|
21507
|
+
}
|
|
21508
|
+
});
|
|
21321
21509
|
// src/portal/inMemorySetupSessionStore.ts
|
|
21322
21510
|
var cloneSession = (value) => ({
|
|
21323
21511
|
...value,
|
|
@@ -21339,19 +21527,19 @@ var createInMemorySetupSessionStore = () => {
|
|
|
21339
21527
|
};
|
|
21340
21528
|
};
|
|
21341
21529
|
// src/portal/postgresSetupSessionStore.ts
|
|
21342
|
-
var
|
|
21530
|
+
var ID_LENGTH16 = 255;
|
|
21343
21531
|
var setupSessionsTable = pgTable("auth_setup_sessions", {
|
|
21344
21532
|
capabilities: jsonb("capabilities").$type().notNull().default([]),
|
|
21345
21533
|
created_at_ms: bigint("created_at_ms", { mode: "number" }).notNull(),
|
|
21346
|
-
created_by: varchar("created_by", { length:
|
|
21534
|
+
created_by: varchar("created_by", { length: ID_LENGTH16 }),
|
|
21347
21535
|
expires_at_ms: bigint("expires_at_ms", { mode: "number" }).notNull(),
|
|
21348
21536
|
organization_id: varchar("organization_id", {
|
|
21349
|
-
length:
|
|
21537
|
+
length: ID_LENGTH16
|
|
21350
21538
|
}).notNull(),
|
|
21351
21539
|
setup_session_id: varchar("setup_session_id", {
|
|
21352
|
-
length:
|
|
21540
|
+
length: ID_LENGTH16
|
|
21353
21541
|
}).primaryKey(),
|
|
21354
|
-
token_hash: varchar("token_hash", { length:
|
|
21542
|
+
token_hash: varchar("token_hash", { length: ID_LENGTH16 }).notNull().unique()
|
|
21355
21543
|
});
|
|
21356
21544
|
var toSession = (row) => ({
|
|
21357
21545
|
capabilities: row.capabilities,
|
|
@@ -21542,6 +21730,7 @@ var auth = async ({
|
|
|
21542
21730
|
};
|
|
21543
21731
|
export {
|
|
21544
21732
|
writeWarrant,
|
|
21733
|
+
webhookDeliveriesTable,
|
|
21545
21734
|
webauthnRoutes,
|
|
21546
21735
|
webauthnCredentialsTable,
|
|
21547
21736
|
warrantsTable,
|
|
@@ -21707,6 +21896,7 @@ export {
|
|
|
21707
21896
|
createRiskEngine,
|
|
21708
21897
|
createRedisLockoutStore,
|
|
21709
21898
|
createRedisAuthSessionStore,
|
|
21899
|
+
createPostgresWebhookDeliveryStore,
|
|
21710
21900
|
createPostgresWebAuthnCredentialStore,
|
|
21711
21901
|
createPostgresWarrantStore,
|
|
21712
21902
|
createPostgresVaultStore,
|
|
@@ -21731,6 +21921,7 @@ export {
|
|
|
21731
21921
|
createPostgresAccessTokenStore,
|
|
21732
21922
|
createOrganization,
|
|
21733
21923
|
createOAuthLinkedProviderCredentialResolver,
|
|
21924
|
+
createNeonWebhookDeliveryStore,
|
|
21734
21925
|
createNeonWebAuthnCredentialStore,
|
|
21735
21926
|
createNeonWarrantStore,
|
|
21736
21927
|
createNeonVaultStore,
|
|
@@ -21761,6 +21952,7 @@ export {
|
|
|
21761
21952
|
createMembershipPermissionResolver,
|
|
21762
21953
|
createLockoutGuard,
|
|
21763
21954
|
createLinkedProviderCredentialResolver,
|
|
21955
|
+
createInMemoryWebhookDeliveryStore,
|
|
21764
21956
|
createInMemoryWebAuthnCredentialStore,
|
|
21765
21957
|
createInMemoryWarrantStore,
|
|
21766
21958
|
createInMemoryVaultStore,
|
|
@@ -21818,6 +22010,7 @@ export {
|
|
|
21818
22010
|
acceptInvitation,
|
|
21819
22011
|
WEBAUTHN_CHALLENGE_COOKIE,
|
|
21820
22012
|
DEFAULT_WEBHOOK_TIMEOUT_MS,
|
|
22013
|
+
DEFAULT_WEBHOOK_RETRY,
|
|
21821
22014
|
DEFAULT_WEBAUTHN_SESSION_TTL_MS,
|
|
21822
22015
|
DEFAULT_WEBAUTHN_ROUTE,
|
|
21823
22016
|
DEFAULT_WEBAUTHN_CHALLENGE_TTL_MS,
|
|
@@ -21846,5 +22039,5 @@ export {
|
|
|
21846
22039
|
AuthIdentityConflictError
|
|
21847
22040
|
};
|
|
21848
22041
|
|
|
21849
|
-
//# debugId=
|
|
22042
|
+
//# debugId=451C9751C02E5E2164756E2164756E21
|
|
21850
22043
|
//# sourceMappingURL=index.js.map
|