@finueva/auth 0.16.0 → 0.17.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/device.d.ts +3 -2
- package/dist/device.js +117 -39
- package/dist/index.d.ts +2 -2
- package/dist/index.js +107 -8
- package/dist/server.d.ts +26 -2
- package/dist/server.js +2428 -1169
- package/dist/{types-Dpy17xNC.d.ts → types-CqFT4G95.d.ts} +13 -1
- package/package.json +4 -2
package/dist/device.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { C as OrganizationPage, D as OrganizationTeamMemberPage, E as OrganizationTeamDisplay, G as SocialIdTokenProvider, J as UpdateProfileInput, K as UpdateOrganizationDisplayInput, O as OrganizationTeamPage, Q as AuthErrorStatus, R as ReceivedOrganizationInvitation, S as OrganizationMemberPage, T as OrganizationTeam, W as SocialIdTokenInput, X as AuthError, Z as AuthErrorCode, _ as OrganizationDisplay, b as OrganizationMember, d as CreatedOrganizationMemberInvitation, f as CreatedOrganizationTeam, m as DriveCredentialInput, o as AuthSession, p as DriveCredential, q as UpdateOrganizationTeamDisplayInput, r as AuthOrganization, u as CreateOrganizationMemberInvitationInput, v as OrganizationInvitation, w as OrganizationPageInput, x as OrganizationMemberAuthority, y as OrganizationInvitationPage, z as ReceivedOrganizationInvitationPage } from "./types-
|
|
1
|
+
import { $ as UserApiCredential, C as OrganizationPage, D as OrganizationTeamMemberPage, E as OrganizationTeamDisplay, G as SocialIdTokenProvider, J as UpdateProfileInput, K as UpdateOrganizationDisplayInput, O as OrganizationTeamPage, Q as AuthErrorStatus, R as ReceivedOrganizationInvitation, S as OrganizationMemberPage, T as OrganizationTeam, W as SocialIdTokenInput, X as AuthError, Z as AuthErrorCode, _ as OrganizationDisplay, b as OrganizationMember, d as CreatedOrganizationMemberInvitation, et as UserApiCredentialInput, f as CreatedOrganizationTeam, m as DriveCredentialInput, o as AuthSession, p as DriveCredential, q as UpdateOrganizationTeamDisplayInput, r as AuthOrganization, u as CreateOrganizationMemberInvitationInput, v as OrganizationInvitation, w as OrganizationPageInput, x as OrganizationMemberAuthority, y as OrganizationInvitationPage, z as ReceivedOrganizationInvitationPage } from "./types-CqFT4G95.js";
|
|
2
2
|
//#region src/device.d.ts
|
|
3
3
|
type DeviceAuthorizationErrorCode = "device_access_denied" | "device_authorization_cancelled" | "device_code_expired" | "invalid_device_authorization" | "identity_authority_unavailable";
|
|
4
4
|
declare class DeviceAuthorizationError extends Error {
|
|
@@ -64,9 +64,10 @@ interface DeviceAuthClient {
|
|
|
64
64
|
updateProfile(input: UpdateProfileInput): Promise<AuthSession>;
|
|
65
65
|
changePassword(currentPassword: string, newPassword: string, revokeOtherSessions?: boolean): Promise<AuthSession>;
|
|
66
66
|
getDriveCredential(input: DriveCredentialInput): Promise<DriveCredential>;
|
|
67
|
+
getUserApiCredential(input: UserApiCredentialInput): Promise<UserApiCredential>;
|
|
67
68
|
revokeCurrentDevice(): Promise<void>;
|
|
68
69
|
revokeAllSessions(): Promise<void>;
|
|
69
70
|
}
|
|
70
71
|
declare function createDeviceAuth(options: DeviceAuthOptions): DeviceAuthClient;
|
|
71
72
|
//#endregion
|
|
72
|
-
export { AuthError, type AuthErrorCode, type AuthErrorStatus, type AuthOrganization, type CreateOrganizationMemberInvitationInput, type CreatedOrganizationMemberInvitation, type CreatedOrganizationTeam, DeviceAuthClient, DeviceAuthOptions, DeviceAuthorization, DeviceAuthorizationError, DeviceAuthorizationErrorCode, DeviceToken, DeviceTokenPersistence, type OrganizationDisplay, type OrganizationInvitation, type OrganizationInvitationPage, type OrganizationMember, type OrganizationMemberAuthority, type OrganizationMemberPage, type OrganizationPage, type OrganizationPageInput, type OrganizationTeam, type OrganizationTeamDisplay, type OrganizationTeamMemberPage, type OrganizationTeamPage, PollDeviceOptions, type ReceivedOrganizationInvitation, type ReceivedOrganizationInvitationPage, type SocialIdTokenInput, type SocialIdTokenProvider, type UpdateOrganizationDisplayInput, type UpdateOrganizationTeamDisplayInput, createDeviceAuth };
|
|
73
|
+
export { AuthError, type AuthErrorCode, type AuthErrorStatus, type AuthOrganization, type CreateOrganizationMemberInvitationInput, type CreatedOrganizationMemberInvitation, type CreatedOrganizationTeam, DeviceAuthClient, DeviceAuthOptions, DeviceAuthorization, DeviceAuthorizationError, DeviceAuthorizationErrorCode, DeviceToken, DeviceTokenPersistence, type OrganizationDisplay, type OrganizationInvitation, type OrganizationInvitationPage, type OrganizationMember, type OrganizationMemberAuthority, type OrganizationMemberPage, type OrganizationPage, type OrganizationPageInput, type OrganizationTeam, type OrganizationTeamDisplay, type OrganizationTeamMemberPage, type OrganizationTeamPage, PollDeviceOptions, type ReceivedOrganizationInvitation, type ReceivedOrganizationInvitationPage, type SocialIdTokenInput, type SocialIdTokenProvider, type UpdateOrganizationDisplayInput, type UpdateOrganizationTeamDisplayInput, type UserApiCredential, type UserApiCredentialInput, createDeviceAuth };
|
package/dist/device.js
CHANGED
|
@@ -173,6 +173,109 @@ function stringifyParsedURL(parsed) {
|
|
|
173
173
|
return (parsed.protocol || parsed[protocolRelative] ? (parsed.protocol || "") + "//" : "") + auth + host + pathname + search + hash;
|
|
174
174
|
}
|
|
175
175
|
//#endregion
|
|
176
|
+
//#region src/errors.ts
|
|
177
|
+
const messages = {
|
|
178
|
+
invalid_credentials: "The credentials are invalid.",
|
|
179
|
+
invalid_auth_input: "The authentication input is invalid.",
|
|
180
|
+
account_conflict: "The account is not available.",
|
|
181
|
+
password_reset_invalid: "The password reset request is invalid.",
|
|
182
|
+
authentication_required: "Authentication is required.",
|
|
183
|
+
request_origin_denied: "The request origin is not allowed.",
|
|
184
|
+
invalid_request: "The request is invalid.",
|
|
185
|
+
invalid_invitation: "The invitation is invalid.",
|
|
186
|
+
invitation_unavailable: "The invitation is not available.",
|
|
187
|
+
recipient_unavailable: "The recipient is unavailable.",
|
|
188
|
+
invitation_recipient_mismatch: "The invitation cannot be accepted by this account.",
|
|
189
|
+
invitation_recovery_required: "Invitation administration requires separate recovery.",
|
|
190
|
+
email_verification_required: "Email verification is required.",
|
|
191
|
+
invalid_workspace_selection: "The workspace selection is invalid.",
|
|
192
|
+
organization_context_too_large: "The organization context is too large.",
|
|
193
|
+
credential_rate_limited: "Credential requests are temporarily limited.",
|
|
194
|
+
auth_request_rate_limited: "Authentication requests are temporarily limited.",
|
|
195
|
+
state_conflict: "The authentication state conflicts with the request.",
|
|
196
|
+
access_denied: "Access is denied.",
|
|
197
|
+
platform_target_unavailable: "The platform administration target is unavailable.",
|
|
198
|
+
platform_quorum_unavailable: "Platform administration quorum is unavailable.",
|
|
199
|
+
platform_recovery_required: "Platform administration requires separate recovery.",
|
|
200
|
+
identity_authority_unavailable: "Authentication is temporarily unavailable."
|
|
201
|
+
};
|
|
202
|
+
var AuthError = class extends Error {
|
|
203
|
+
code;
|
|
204
|
+
status;
|
|
205
|
+
retryAfterSeconds;
|
|
206
|
+
constructor(code, status, retryAfterSeconds) {
|
|
207
|
+
super(messages[code]);
|
|
208
|
+
this.name = "AuthError";
|
|
209
|
+
this.code = code;
|
|
210
|
+
this.status = status;
|
|
211
|
+
this.retryAfterSeconds = retryAfterSeconds;
|
|
212
|
+
}
|
|
213
|
+
};
|
|
214
|
+
//#endregion
|
|
215
|
+
//#region src/user-api/credential.ts
|
|
216
|
+
function userApiApplication(input) {
|
|
217
|
+
if (!input || typeof input.applicationId !== "string" || !/^[A-Za-z0-9_-]{1,128}$(?![\s\S])/.test(input.applicationId) || input.forceRefresh !== void 0 && typeof input.forceRefresh !== "boolean") throw new TypeError("User API credential input is invalid");
|
|
218
|
+
return input.applicationId;
|
|
219
|
+
}
|
|
220
|
+
function normalizeUserApiCredential(value, startedAt) {
|
|
221
|
+
if (!value || typeof value !== "object" || Array.isArray(value) || !("tokenType" in value) || value.tokenType !== "Bearer" || !("token" in value) || typeof value.token !== "string" || value.token.length + 7 > 16 * 1024 || !/^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/.test(value.token) || !("expiresIn" in value) || typeof value.expiresIn !== "number" || !Number.isInteger(value.expiresIn) || value.expiresIn < 1 || value.expiresIn > 840 || Object.keys(value).sort().join(",") !== "expiresIn,token,tokenType") throw new AuthError("identity_authority_unavailable", 503);
|
|
222
|
+
return {
|
|
223
|
+
tokenType: "Bearer",
|
|
224
|
+
token: value.token,
|
|
225
|
+
expiresAt: new Date(startedAt + value.expiresIn * 1e3)
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
function createUserApiCredentialCache(issue, now) {
|
|
229
|
+
let generation = 0;
|
|
230
|
+
let cached;
|
|
231
|
+
let pending;
|
|
232
|
+
const copy = (value) => ({
|
|
233
|
+
...value,
|
|
234
|
+
expiresAt: new Date(value.expiresAt)
|
|
235
|
+
});
|
|
236
|
+
return {
|
|
237
|
+
hasAuthority: () => Boolean(cached || pending),
|
|
238
|
+
clear() {
|
|
239
|
+
generation += 1;
|
|
240
|
+
cached = void 0;
|
|
241
|
+
pending = void 0;
|
|
242
|
+
},
|
|
243
|
+
async get(input) {
|
|
244
|
+
const applicationId = userApiApplication(input);
|
|
245
|
+
if (pending) {
|
|
246
|
+
if (pending.applicationId !== applicationId) throw new AuthError("state_conflict", 409);
|
|
247
|
+
return copy(await pending.request);
|
|
248
|
+
}
|
|
249
|
+
const startedAt = now();
|
|
250
|
+
if (!input.forceRefresh && cached?.applicationId === applicationId && cached.expiresAt - startedAt > 12e4) return {
|
|
251
|
+
tokenType: "Bearer",
|
|
252
|
+
token: cached.token,
|
|
253
|
+
expiresAt: new Date(cached.expiresAt)
|
|
254
|
+
};
|
|
255
|
+
cached = void 0;
|
|
256
|
+
const epoch = generation;
|
|
257
|
+
const request = (async () => {
|
|
258
|
+
const value = normalizeUserApiCredential(await issue(applicationId), startedAt);
|
|
259
|
+
if (epoch !== generation) throw new AuthError("state_conflict", 409);
|
|
260
|
+
if (now() < startedAt || value.expiresAt.getTime() <= now()) throw new AuthError("authentication_required", 401);
|
|
261
|
+
cached = {
|
|
262
|
+
applicationId,
|
|
263
|
+
token: value.token,
|
|
264
|
+
expiresAt: value.expiresAt.getTime()
|
|
265
|
+
};
|
|
266
|
+
return value;
|
|
267
|
+
})().finally(() => {
|
|
268
|
+
if (pending?.request === request) pending = void 0;
|
|
269
|
+
});
|
|
270
|
+
pending = {
|
|
271
|
+
applicationId,
|
|
272
|
+
request
|
|
273
|
+
};
|
|
274
|
+
return copy(await request);
|
|
275
|
+
}
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
//#endregion
|
|
176
279
|
//#region ../../node_modules/.pnpm/destr@2.0.5/node_modules/destr/dist/index.mjs
|
|
177
280
|
const suspectProtoRx = /"(?:_|\\u0{2}5[Ff]){2}(?:p|\\u0{2}70)(?:r|\\u0{2}72)(?:o|\\u0{2}6[Ff])(?:t|\\u0{2}74)(?:o|\\u0{2}6[Ff])(?:_|\\u0{2}5[Ff]){2}"\s*:/;
|
|
178
281
|
const suspectConstructorRx = /"(?:c|\\u0063)(?:o|\\u006[Ff])(?:n|\\u006[Ee])(?:s|\\u0073)(?:t|\\u0074)(?:r|\\u0072)(?:u|\\u0075)(?:c|\\u0063)(?:t|\\u0074)(?:o|\\u006[Ff])(?:r|\\u0072)"\s*:/;
|
|
@@ -436,45 +539,6 @@ function createFetch(globalOptions = {}) {
|
|
|
436
539
|
return $fetch;
|
|
437
540
|
}
|
|
438
541
|
//#endregion
|
|
439
|
-
//#region src/errors.ts
|
|
440
|
-
const messages = {
|
|
441
|
-
invalid_credentials: "The credentials are invalid.",
|
|
442
|
-
invalid_auth_input: "The authentication input is invalid.",
|
|
443
|
-
account_conflict: "The account is not available.",
|
|
444
|
-
password_reset_invalid: "The password reset request is invalid.",
|
|
445
|
-
authentication_required: "Authentication is required.",
|
|
446
|
-
request_origin_denied: "The request origin is not allowed.",
|
|
447
|
-
invalid_request: "The request is invalid.",
|
|
448
|
-
invalid_invitation: "The invitation is invalid.",
|
|
449
|
-
invitation_unavailable: "The invitation is not available.",
|
|
450
|
-
recipient_unavailable: "The recipient is unavailable.",
|
|
451
|
-
invitation_recipient_mismatch: "The invitation cannot be accepted by this account.",
|
|
452
|
-
invitation_recovery_required: "Invitation administration requires separate recovery.",
|
|
453
|
-
email_verification_required: "Email verification is required.",
|
|
454
|
-
invalid_workspace_selection: "The workspace selection is invalid.",
|
|
455
|
-
organization_context_too_large: "The organization context is too large.",
|
|
456
|
-
credential_rate_limited: "Credential requests are temporarily limited.",
|
|
457
|
-
auth_request_rate_limited: "Authentication requests are temporarily limited.",
|
|
458
|
-
state_conflict: "The authentication state conflicts with the request.",
|
|
459
|
-
access_denied: "Access is denied.",
|
|
460
|
-
platform_target_unavailable: "The platform administration target is unavailable.",
|
|
461
|
-
platform_quorum_unavailable: "Platform administration quorum is unavailable.",
|
|
462
|
-
platform_recovery_required: "Platform administration requires separate recovery.",
|
|
463
|
-
identity_authority_unavailable: "Authentication is temporarily unavailable."
|
|
464
|
-
};
|
|
465
|
-
var AuthError = class extends Error {
|
|
466
|
-
code;
|
|
467
|
-
status;
|
|
468
|
-
retryAfterSeconds;
|
|
469
|
-
constructor(code, status, retryAfterSeconds) {
|
|
470
|
-
super(messages[code]);
|
|
471
|
-
this.name = "AuthError";
|
|
472
|
-
this.code = code;
|
|
473
|
-
this.status = status;
|
|
474
|
-
this.retryAfterSeconds = retryAfterSeconds;
|
|
475
|
-
}
|
|
476
|
-
};
|
|
477
|
-
//#endregion
|
|
478
542
|
//#region src/shared.ts
|
|
479
543
|
const DRIVE_CREDENTIAL_LIFETIME_SECONDS = 840;
|
|
480
544
|
const id = /^[A-Za-z0-9_-]{1,128}$/;
|
|
@@ -1165,7 +1229,18 @@ function createDeviceAuth(options) {
|
|
|
1165
1229
|
let authorityTail = Promise.resolve();
|
|
1166
1230
|
let persistenceTail = Promise.resolve();
|
|
1167
1231
|
let persistencePending = 0;
|
|
1232
|
+
const userApiCredentials = createUserApiCredentialCache(async (applicationId) => {
|
|
1233
|
+
const authority = await serializeAuthority(async () => ({
|
|
1234
|
+
current: await readToken(),
|
|
1235
|
+
generation: authorityGeneration
|
|
1236
|
+
}));
|
|
1237
|
+
if (!authority.current) throw new AuthError("authentication_required", 401);
|
|
1238
|
+
const response = await authenticated("user-api-credential", authority.current, { applicationId });
|
|
1239
|
+
if (authority.generation !== authorityGeneration) throw new AuthError("state_conflict", 409);
|
|
1240
|
+
return response.value;
|
|
1241
|
+
}, now);
|
|
1168
1242
|
function clearCredential() {
|
|
1243
|
+
userApiCredentials.clear();
|
|
1169
1244
|
credential = void 0;
|
|
1170
1245
|
selectedWorkspaceKey = void 0;
|
|
1171
1246
|
credentialGeneration += 1;
|
|
@@ -1782,6 +1857,9 @@ function createDeviceAuth(options) {
|
|
|
1782
1857
|
return session;
|
|
1783
1858
|
}, true);
|
|
1784
1859
|
},
|
|
1860
|
+
getUserApiCredential(input) {
|
|
1861
|
+
return userApiCredentials.get(input);
|
|
1862
|
+
},
|
|
1785
1863
|
getDriveCredential(input) {
|
|
1786
1864
|
let workspace;
|
|
1787
1865
|
let forceRefresh;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { A as PersonalWorkspaceSelection, B as RecentAuthenticationStatus, C as OrganizationPage, D as OrganizationTeamMemberPage, E as OrganizationTeamDisplay, F as PlatformRoleChangeRecentAuthenticationInput, G as SocialIdTokenProvider, H as SendVerificationEmailInput, I as PlatformRoleFirstApproval, J as UpdateProfileInput, K as UpdateOrganizationDisplayInput, L as PlatformStatus, M as PlatformRole, N as PlatformRoleApplied, O as OrganizationTeamPage, P as PlatformRoleApproval, Q as AuthErrorStatus, R as ReceivedOrganizationInvitation, S as OrganizationMemberPage, T as OrganizationTeam, U as SignInInput, V as ResentOrganizationInvitation, W as SocialIdTokenInput, X as AuthError, Y as WorkspaceSelection, Z as AuthErrorCode, _ as OrganizationDisplay, a as AuthPersistenceDriver, b as OrganizationMember, c as AuthUser, d as CreatedOrganizationMemberInvitation, f as CreatedOrganizationTeam, g as InvitationAcceptance, h as FinuevaAuthClient, i as AuthPersistence, j as PlatformBootstrapRoleChangeInput, k as OrganizationWorkspaceSelection, l as CanceledOrganizationInvitation, m as DriveCredentialInput, n as AuthClientOptions, o as AuthSession, p as DriveCredential, q as UpdateOrganizationTeamDisplayInput, r as AuthOrganization, s as AuthState, t as AcceptInvitationInput, u as CreateOrganizationMemberInvitationInput, v as OrganizationInvitation, w as OrganizationPageInput, x as OrganizationMemberAuthority, y as OrganizationInvitationPage, z as ReceivedOrganizationInvitationPage } from "./types-
|
|
1
|
+
import { $ as UserApiCredential, A as PersonalWorkspaceSelection, B as RecentAuthenticationStatus, C as OrganizationPage, D as OrganizationTeamMemberPage, E as OrganizationTeamDisplay, F as PlatformRoleChangeRecentAuthenticationInput, G as SocialIdTokenProvider, H as SendVerificationEmailInput, I as PlatformRoleFirstApproval, J as UpdateProfileInput, K as UpdateOrganizationDisplayInput, L as PlatformStatus, M as PlatformRole, N as PlatformRoleApplied, O as OrganizationTeamPage, P as PlatformRoleApproval, Q as AuthErrorStatus, R as ReceivedOrganizationInvitation, S as OrganizationMemberPage, T as OrganizationTeam, U as SignInInput, V as ResentOrganizationInvitation, W as SocialIdTokenInput, X as AuthError, Y as WorkspaceSelection, Z as AuthErrorCode, _ as OrganizationDisplay, a as AuthPersistenceDriver, b as OrganizationMember, c as AuthUser, d as CreatedOrganizationMemberInvitation, et as UserApiCredentialInput, f as CreatedOrganizationTeam, g as InvitationAcceptance, h as FinuevaAuthClient, i as AuthPersistence, j as PlatformBootstrapRoleChangeInput, k as OrganizationWorkspaceSelection, l as CanceledOrganizationInvitation, m as DriveCredentialInput, n as AuthClientOptions, o as AuthSession, p as DriveCredential, q as UpdateOrganizationTeamDisplayInput, r as AuthOrganization, s as AuthState, t as AcceptInvitationInput, u as CreateOrganizationMemberInvitationInput, v as OrganizationInvitation, w as OrganizationPageInput, x as OrganizationMemberAuthority, y as OrganizationInvitationPage, z as ReceivedOrganizationInvitationPage } from "./types-CqFT4G95.js";
|
|
2
2
|
//#region src/client.d.ts
|
|
3
3
|
declare function createAuthClient(options: AuthClientOptions): FinuevaAuthClient;
|
|
4
4
|
//#endregion
|
|
5
|
-
export { type AcceptInvitationInput, type AuthClientOptions, AuthError, type AuthErrorCode, type AuthErrorStatus, type AuthOrganization, type AuthPersistence, type AuthPersistenceDriver, type AuthSession, type AuthState, type AuthUser, type CanceledOrganizationInvitation, type CreateOrganizationMemberInvitationInput, type CreatedOrganizationMemberInvitation, type CreatedOrganizationTeam, type DriveCredential, type DriveCredentialInput, type FinuevaAuthClient, type InvitationAcceptance, type OrganizationDisplay, type OrganizationInvitation, type OrganizationInvitationPage, type OrganizationMember, type OrganizationMemberAuthority, type OrganizationMemberPage, type OrganizationPage, type OrganizationPageInput, type OrganizationTeam, type OrganizationTeamDisplay, type OrganizationTeamMemberPage, type OrganizationTeamPage, type OrganizationWorkspaceSelection, type PersonalWorkspaceSelection, type PlatformBootstrapRoleChangeInput, type PlatformRole, type PlatformRoleApplied, type PlatformRoleApproval, type PlatformRoleChangeRecentAuthenticationInput, type PlatformRoleFirstApproval, type PlatformStatus, type ReceivedOrganizationInvitation, type ReceivedOrganizationInvitationPage, type RecentAuthenticationStatus, type ResentOrganizationInvitation, type SendVerificationEmailInput, type SignInInput, type SocialIdTokenInput, type SocialIdTokenProvider, type UpdateOrganizationDisplayInput, type UpdateOrganizationTeamDisplayInput, type UpdateProfileInput, type WorkspaceSelection, createAuthClient };
|
|
5
|
+
export { type AcceptInvitationInput, type AuthClientOptions, AuthError, type AuthErrorCode, type AuthErrorStatus, type AuthOrganization, type AuthPersistence, type AuthPersistenceDriver, type AuthSession, type AuthState, type AuthUser, type CanceledOrganizationInvitation, type CreateOrganizationMemberInvitationInput, type CreatedOrganizationMemberInvitation, type CreatedOrganizationTeam, type DriveCredential, type DriveCredentialInput, type FinuevaAuthClient, type InvitationAcceptance, type OrganizationDisplay, type OrganizationInvitation, type OrganizationInvitationPage, type OrganizationMember, type OrganizationMemberAuthority, type OrganizationMemberPage, type OrganizationPage, type OrganizationPageInput, type OrganizationTeam, type OrganizationTeamDisplay, type OrganizationTeamMemberPage, type OrganizationTeamPage, type OrganizationWorkspaceSelection, type PersonalWorkspaceSelection, type PlatformBootstrapRoleChangeInput, type PlatformRole, type PlatformRoleApplied, type PlatformRoleApproval, type PlatformRoleChangeRecentAuthenticationInput, type PlatformRoleFirstApproval, type PlatformStatus, type ReceivedOrganizationInvitation, type ReceivedOrganizationInvitationPage, type RecentAuthenticationStatus, type ResentOrganizationInvitation, type SendVerificationEmailInput, type SignInInput, type SocialIdTokenInput, type SocialIdTokenProvider, type UpdateOrganizationDisplayInput, type UpdateOrganizationTeamDisplayInput, type UpdateProfileInput, type UserApiCredential, type UserApiCredentialInput, type WorkspaceSelection, createAuthClient };
|
package/dist/index.js
CHANGED
|
@@ -4456,6 +4456,70 @@ function byteLength(value) {
|
|
|
4456
4456
|
return new TextEncoder().encode(value).byteLength;
|
|
4457
4457
|
}
|
|
4458
4458
|
//#endregion
|
|
4459
|
+
//#region src/user-api/credential.ts
|
|
4460
|
+
function userApiApplication(input) {
|
|
4461
|
+
if (!input || typeof input.applicationId !== "string" || !/^[A-Za-z0-9_-]{1,128}$(?![\s\S])/.test(input.applicationId) || input.forceRefresh !== void 0 && typeof input.forceRefresh !== "boolean") throw new TypeError("User API credential input is invalid");
|
|
4462
|
+
return input.applicationId;
|
|
4463
|
+
}
|
|
4464
|
+
function normalizeUserApiCredential(value, startedAt) {
|
|
4465
|
+
if (!value || typeof value !== "object" || Array.isArray(value) || !("tokenType" in value) || value.tokenType !== "Bearer" || !("token" in value) || typeof value.token !== "string" || value.token.length + 7 > 16 * 1024 || !/^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/.test(value.token) || !("expiresIn" in value) || typeof value.expiresIn !== "number" || !Number.isInteger(value.expiresIn) || value.expiresIn < 1 || value.expiresIn > 840 || Object.keys(value).sort().join(",") !== "expiresIn,token,tokenType") throw new AuthError("identity_authority_unavailable", 503);
|
|
4466
|
+
return {
|
|
4467
|
+
tokenType: "Bearer",
|
|
4468
|
+
token: value.token,
|
|
4469
|
+
expiresAt: new Date(startedAt + value.expiresIn * 1e3)
|
|
4470
|
+
};
|
|
4471
|
+
}
|
|
4472
|
+
function createUserApiCredentialCache(issue, now) {
|
|
4473
|
+
let generation = 0;
|
|
4474
|
+
let cached;
|
|
4475
|
+
let pending;
|
|
4476
|
+
const copy = (value) => ({
|
|
4477
|
+
...value,
|
|
4478
|
+
expiresAt: new Date(value.expiresAt)
|
|
4479
|
+
});
|
|
4480
|
+
return {
|
|
4481
|
+
hasAuthority: () => Boolean(cached || pending),
|
|
4482
|
+
clear() {
|
|
4483
|
+
generation += 1;
|
|
4484
|
+
cached = void 0;
|
|
4485
|
+
pending = void 0;
|
|
4486
|
+
},
|
|
4487
|
+
async get(input) {
|
|
4488
|
+
const applicationId = userApiApplication(input);
|
|
4489
|
+
if (pending) {
|
|
4490
|
+
if (pending.applicationId !== applicationId) throw new AuthError("state_conflict", 409);
|
|
4491
|
+
return copy(await pending.request);
|
|
4492
|
+
}
|
|
4493
|
+
const startedAt = now();
|
|
4494
|
+
if (!input.forceRefresh && cached?.applicationId === applicationId && cached.expiresAt - startedAt > 12e4) return {
|
|
4495
|
+
tokenType: "Bearer",
|
|
4496
|
+
token: cached.token,
|
|
4497
|
+
expiresAt: new Date(cached.expiresAt)
|
|
4498
|
+
};
|
|
4499
|
+
cached = void 0;
|
|
4500
|
+
const epoch = generation;
|
|
4501
|
+
const request = (async () => {
|
|
4502
|
+
const value = normalizeUserApiCredential(await issue(applicationId), startedAt);
|
|
4503
|
+
if (epoch !== generation) throw new AuthError("state_conflict", 409);
|
|
4504
|
+
if (now() < startedAt || value.expiresAt.getTime() <= now()) throw new AuthError("authentication_required", 401);
|
|
4505
|
+
cached = {
|
|
4506
|
+
applicationId,
|
|
4507
|
+
token: value.token,
|
|
4508
|
+
expiresAt: value.expiresAt.getTime()
|
|
4509
|
+
};
|
|
4510
|
+
return value;
|
|
4511
|
+
})().finally(() => {
|
|
4512
|
+
if (pending?.request === request) pending = void 0;
|
|
4513
|
+
});
|
|
4514
|
+
pending = {
|
|
4515
|
+
applicationId,
|
|
4516
|
+
request
|
|
4517
|
+
};
|
|
4518
|
+
return copy(await request);
|
|
4519
|
+
}
|
|
4520
|
+
};
|
|
4521
|
+
}
|
|
4522
|
+
//#endregion
|
|
4459
4523
|
//#region src/client.ts
|
|
4460
4524
|
const REFRESH_WINDOW_MS = 120 * 1e3;
|
|
4461
4525
|
const RECENT_AUTHENTICATION_BROWSER_HEADER = "x-finueva-recent-auth-browser";
|
|
@@ -4468,11 +4532,18 @@ function createAuthClient(options) {
|
|
|
4468
4532
|
if (typeof fetchImpl !== "function") throw new TypeError("fetch is required");
|
|
4469
4533
|
const now = options.now ?? Date.now;
|
|
4470
4534
|
const timeoutMs = normalizeTimeout(options.timeoutMs);
|
|
4535
|
+
const userApiCredentials = createUserApiCredentialCache((applicationId) => requestJson(joinURL(authOrigin, "api/v1/auth/user-api-credential"), {
|
|
4536
|
+
fetch: fetchImpl,
|
|
4537
|
+
timeoutMs,
|
|
4538
|
+
method: "POST",
|
|
4539
|
+
headers: { "content-type": "application/json; charset=utf-8" },
|
|
4540
|
+
body: { applicationId }
|
|
4541
|
+
}), now);
|
|
4471
4542
|
const betterAuth = createAuthClient$1({
|
|
4472
4543
|
baseURL: authOrigin,
|
|
4473
4544
|
basePath: "/api/v1/auth",
|
|
4474
4545
|
fetchOptions: {
|
|
4475
|
-
customFetchImpl:
|
|
4546
|
+
customFetchImpl: fetchBetterAuth,
|
|
4476
4547
|
credentials: "include",
|
|
4477
4548
|
retry: 0,
|
|
4478
4549
|
timeout: timeoutMs
|
|
@@ -4508,6 +4579,15 @@ function createAuthClient(options) {
|
|
|
4508
4579
|
let signalRefreshPending = false;
|
|
4509
4580
|
let signalRefreshScheduled = false;
|
|
4510
4581
|
let signalRefreshRequest;
|
|
4582
|
+
let betterAuthTransportSequence = 0;
|
|
4583
|
+
async function fetchBetterAuth(input, init) {
|
|
4584
|
+
const request = new Request(input, init);
|
|
4585
|
+
const url = new URL(request.url);
|
|
4586
|
+
if (!authStateStarted || request.method !== "GET" || url.origin !== authOrigin || url.pathname !== "/api/v1/auth/get-session" || signOutRequest || activeAccountMutationGeneration !== void 0) return fetchImpl(input, init);
|
|
4587
|
+
betterAuthTransportSequence += 1;
|
|
4588
|
+
const response = await readAuthoritySession(authorityGeneration, request);
|
|
4589
|
+
return new Response(JSON.stringify(response.value), { headers: { "content-type": "application/json" } });
|
|
4590
|
+
}
|
|
4511
4591
|
function advanceAuthorityGeneration() {
|
|
4512
4592
|
recentAuthenticationStartAttempt = void 0;
|
|
4513
4593
|
return ++authorityGeneration;
|
|
@@ -4569,12 +4649,13 @@ function createAuthClient(options) {
|
|
|
4569
4649
|
authoritative: false
|
|
4570
4650
|
});
|
|
4571
4651
|
});
|
|
4572
|
-
getSession().catch(() => void 0);
|
|
4652
|
+
if (typeof window === "undefined") getSession().catch(() => void 0);
|
|
4573
4653
|
}
|
|
4574
4654
|
function subscribeToSessionSignals() {
|
|
4575
4655
|
if (sessionSignalSubscribed) return;
|
|
4576
4656
|
sessionSignalSubscribed = true;
|
|
4577
4657
|
let initialized = false;
|
|
4658
|
+
let transportSequence = betterAuthTransportSequence;
|
|
4578
4659
|
betterAuth.useSession.subscribe((state) => {
|
|
4579
4660
|
const refetching = state.isRefetching === true;
|
|
4580
4661
|
if (!initialized) {
|
|
@@ -4583,6 +4664,7 @@ function createAuthClient(options) {
|
|
|
4583
4664
|
return;
|
|
4584
4665
|
}
|
|
4585
4666
|
const settled = betterAuthRefetching && !refetching;
|
|
4667
|
+
if (refetching && !betterAuthRefetching) transportSequence = betterAuthTransportSequence;
|
|
4586
4668
|
betterAuthRefetching = refetching;
|
|
4587
4669
|
if (refetching && signOutRequest) suppressBetterAuthSettlement = true;
|
|
4588
4670
|
if (!settled) return;
|
|
@@ -4590,6 +4672,7 @@ function createAuthClient(options) {
|
|
|
4590
4672
|
suppressBetterAuthSettlement = false;
|
|
4591
4673
|
return;
|
|
4592
4674
|
}
|
|
4675
|
+
if (transportSequence !== betterAuthTransportSequence) return;
|
|
4593
4676
|
queueSignalRefresh();
|
|
4594
4677
|
});
|
|
4595
4678
|
}
|
|
@@ -4610,13 +4693,14 @@ function createAuthClient(options) {
|
|
|
4610
4693
|
signalRefreshRequest = request;
|
|
4611
4694
|
}
|
|
4612
4695
|
function clearCredential() {
|
|
4696
|
+
userApiCredentials.clear();
|
|
4613
4697
|
credential = void 0;
|
|
4614
4698
|
credentialRequests.clear();
|
|
4615
4699
|
selectedWorkspaceKey = void 0;
|
|
4616
4700
|
credentialGeneration += 1;
|
|
4617
4701
|
}
|
|
4618
4702
|
function updateSession(session) {
|
|
4619
|
-
const unboundCredential = !sessionId && (credential || credentialRequests.size > 0);
|
|
4703
|
+
const unboundCredential = !sessionId && (credential || credentialRequests.size > 0 || userApiCredentials.hasAuthority());
|
|
4620
4704
|
const changedSession = sessionId === void 0 ? !sessionAuthorityObserved || session !== null : !session || session.id !== sessionId || session.user.id !== sessionUserId;
|
|
4621
4705
|
if (!session || unboundCredential || sessionId && (session.id !== sessionId || session.user.id !== sessionUserId)) clearCredential();
|
|
4622
4706
|
if (changedSession || recentAuthenticationStartAttempt && (recentAuthenticationStartAttempt.sessionId !== session?.id || recentAuthenticationStartAttempt.userId !== session?.user.id)) recentAuthenticationStartAttempt = void 0;
|
|
@@ -4626,24 +4710,35 @@ function createAuthClient(options) {
|
|
|
4626
4710
|
sessionUserId = session?.user.id;
|
|
4627
4711
|
return session;
|
|
4628
4712
|
}
|
|
4629
|
-
async function
|
|
4713
|
+
async function readAuthoritySession(generation, request) {
|
|
4630
4714
|
const readEpoch = ++sessionReadEpoch;
|
|
4631
4715
|
try {
|
|
4632
|
-
const response = await requestJsonResponse(joinURL(authOrigin, "api/v1/auth/get-session"), {
|
|
4716
|
+
const response = await requestJsonResponse(request?.url ?? joinURL(authOrigin, "api/v1/auth/get-session"), {
|
|
4633
4717
|
fetch: fetchImpl,
|
|
4634
4718
|
timeoutMs,
|
|
4635
|
-
method: "GET"
|
|
4719
|
+
method: "GET",
|
|
4720
|
+
...request ? {
|
|
4721
|
+
headers: request.headers,
|
|
4722
|
+
signal: request.signal
|
|
4723
|
+
} : {}
|
|
4636
4724
|
});
|
|
4637
4725
|
if (generation !== authorityGeneration || readEpoch !== sessionReadEpoch) throw new AuthError("state_conflict", 409);
|
|
4638
|
-
return
|
|
4726
|
+
return {
|
|
4727
|
+
...response,
|
|
4728
|
+
session: acceptAuthoritySession(normalizeSession(response.value), generation)
|
|
4729
|
+
};
|
|
4639
4730
|
} catch (error) {
|
|
4640
4731
|
if (generation !== authorityGeneration || readEpoch !== sessionReadEpoch) throw new AuthError("state_conflict", 409);
|
|
4641
4732
|
if (error instanceof AuthError && error.code === "state_conflict") throw error;
|
|
4642
|
-
|
|
4733
|
+
if (error instanceof AuthError && error.status === 401) acceptAuthoritySession(null, generation);
|
|
4734
|
+
else unavailable();
|
|
4643
4735
|
if (error instanceof AuthError) throw error;
|
|
4644
4736
|
throw authorityUnavailable();
|
|
4645
4737
|
}
|
|
4646
4738
|
}
|
|
4739
|
+
async function refreshAuthoritySession(generation) {
|
|
4740
|
+
return (await readAuthoritySession(generation)).session;
|
|
4741
|
+
}
|
|
4647
4742
|
function getSession() {
|
|
4648
4743
|
if (signOutRequest || activeAccountMutationGeneration !== void 0) return Promise.reject(new AuthError("state_conflict", 409));
|
|
4649
4744
|
return refreshAuthoritySession(authorityGeneration);
|
|
@@ -5174,6 +5269,10 @@ function createAuthClient(options) {
|
|
|
5174
5269
|
}));
|
|
5175
5270
|
},
|
|
5176
5271
|
signOut,
|
|
5272
|
+
getUserApiCredential(input) {
|
|
5273
|
+
if (invitationRequest || signOutRequest || activeAccountMutationGeneration !== void 0) return Promise.reject(new AuthError("state_conflict", 409));
|
|
5274
|
+
return userApiCredentials.get(input);
|
|
5275
|
+
},
|
|
5177
5276
|
getDriveCredential(input) {
|
|
5178
5277
|
let workspace;
|
|
5179
5278
|
try {
|
package/dist/server.d.ts
CHANGED
|
@@ -1,4 +1,27 @@
|
|
|
1
|
-
import { A as PersonalWorkspaceSelection, C as OrganizationPage, D as OrganizationTeamMemberPage, E as OrganizationTeamDisplay, G as SocialIdTokenProvider, K as UpdateOrganizationDisplayInput, O as OrganizationTeamPage, Q as AuthErrorStatus, R as ReceivedOrganizationInvitation, S as OrganizationMemberPage, T as OrganizationTeam, V as ResentOrganizationInvitation, W as SocialIdTokenInput, X as AuthError, Y as WorkspaceSelection, Z as AuthErrorCode, _ as OrganizationDisplay, b as OrganizationMember, c as AuthUser, d as CreatedOrganizationMemberInvitation, f as CreatedOrganizationTeam, g as InvitationAcceptance, k as OrganizationWorkspaceSelection, l as CanceledOrganizationInvitation, m as DriveCredentialInput, o as AuthSession, p as DriveCredential, q as UpdateOrganizationTeamDisplayInput, r as AuthOrganization, t as AcceptInvitationInput, u as CreateOrganizationMemberInvitationInput, v as OrganizationInvitation, w as OrganizationPageInput, x as OrganizationMemberAuthority, y as OrganizationInvitationPage, z as ReceivedOrganizationInvitationPage } from "./types-
|
|
1
|
+
import { $ as UserApiCredential, A as PersonalWorkspaceSelection, C as OrganizationPage, D as OrganizationTeamMemberPage, E as OrganizationTeamDisplay, G as SocialIdTokenProvider, K as UpdateOrganizationDisplayInput, O as OrganizationTeamPage, Q as AuthErrorStatus, R as ReceivedOrganizationInvitation, S as OrganizationMemberPage, T as OrganizationTeam, V as ResentOrganizationInvitation, W as SocialIdTokenInput, X as AuthError, Y as WorkspaceSelection, Z as AuthErrorCode, _ as OrganizationDisplay, b as OrganizationMember, c as AuthUser, d as CreatedOrganizationMemberInvitation, et as UserApiCredentialInput, f as CreatedOrganizationTeam, g as InvitationAcceptance, k as OrganizationWorkspaceSelection, l as CanceledOrganizationInvitation, m as DriveCredentialInput, o as AuthSession, p as DriveCredential, q as UpdateOrganizationTeamDisplayInput, r as AuthOrganization, t as AcceptInvitationInput, u as CreateOrganizationMemberInvitationInput, v as OrganizationInvitation, w as OrganizationPageInput, x as OrganizationMemberAuthority, y as OrganizationInvitationPage, z as ReceivedOrganizationInvitationPage } from "./types-CqFT4G95.js";
|
|
2
|
+
//#region src/user-api/verifier.d.ts
|
|
3
|
+
interface UserApiIdentity {
|
|
4
|
+
userId: string;
|
|
5
|
+
sessionId: string;
|
|
6
|
+
applicationId: string;
|
|
7
|
+
issuedAt: Date;
|
|
8
|
+
expiresAt: Date;
|
|
9
|
+
user: AuthUser;
|
|
10
|
+
}
|
|
11
|
+
interface UserApiVerifierOptions {
|
|
12
|
+
issuer: string;
|
|
13
|
+
jwksUrl: string;
|
|
14
|
+
audience: string;
|
|
15
|
+
applicationId: string;
|
|
16
|
+
environment: "local" | "development" | "staging" | "production";
|
|
17
|
+
fetch?: typeof globalThis.fetch;
|
|
18
|
+
now?: () => number;
|
|
19
|
+
}
|
|
20
|
+
/** One configured verifier can be shared. It retains public keys, never user authority. */
|
|
21
|
+
declare function createUserApiVerifier(options: UserApiVerifierOptions): {
|
|
22
|
+
verify(token: string): Promise<UserApiIdentity>;
|
|
23
|
+
};
|
|
24
|
+
//#endregion
|
|
2
25
|
//#region src/identity-resolution.d.ts
|
|
3
26
|
interface IdentityResolverAuthOptions {
|
|
4
27
|
authOrigin: string;
|
|
@@ -94,8 +117,9 @@ interface FinuevaServerAuth {
|
|
|
94
117
|
getReceivedInvitation(invitationId: string): Promise<ReceivedOrganizationInvitation>;
|
|
95
118
|
signInWithSocialIdToken(input: SocialIdTokenInput): Promise<ServerSocialIdTokenSession>;
|
|
96
119
|
getDriveCredential(input: DriveCredentialInput): Promise<DriveCredential>;
|
|
120
|
+
getUserApiCredential(input: UserApiCredentialInput): Promise<UserApiCredential>;
|
|
97
121
|
signOut(): Promise<ServerSignOutResult>;
|
|
98
122
|
}
|
|
99
123
|
declare function createServerAuth(options: ServerAuthOptions): FinuevaServerAuth;
|
|
100
124
|
//#endregion
|
|
101
|
-
export { type AcceptInvitationInput, AuthError, type AuthErrorCode, type AuthErrorStatus, type AuthOrganization, type AuthSession, type AuthUser, type CanceledOrganizationInvitation, type CreateOrganizationMemberInvitationInput, type CreatedOrganizationMemberInvitation, type CreatedOrganizationTeam, type DriveCredential, type DriveCredentialInput, type DriveProvisioningAuthOptions, type DriveProvisioningCredential, type DriveRecipient, type DriveRecipientAuthOptions, type FinuevaDriveProvisioningAuth, type FinuevaDriveRecipientAuth, type FinuevaIdentityResolverAuth, FinuevaServerAuth, type IdentityResolverAuthOptions, type InvitationAcceptance, type OrganizationDisplay, type OrganizationInvitation, type OrganizationInvitationPage, type OrganizationMember, type OrganizationMemberAuthority, type OrganizationMemberPage, type OrganizationPage, type OrganizationPageInput, type OrganizationTeam, type OrganizationTeamDisplay, type OrganizationTeamMemberPage, type OrganizationTeamPage, type OrganizationWorkspaceSelection, type PersonalWorkspaceSelection, type ReceivedOrganizationInvitation, type ReceivedOrganizationInvitationPage, type ResentOrganizationInvitation, type ResolveDriveRecipientInput, type ResolveIdentityInput, type ResolvedIdentity, ServerAuthOptions, ServerInvitationAcceptance, ServerSignOutResult, ServerSocialIdTokenSession, type SocialIdTokenInput, type SocialIdTokenProvider, type UpdateOrganizationDisplayInput, type UpdateOrganizationTeamDisplayInput, type WorkspaceSelection, createDriveProvisioningAuth, createDriveRecipientAuth, createIdentityResolverAuth, createServerAuth };
|
|
125
|
+
export { type AcceptInvitationInput, AuthError, type AuthErrorCode, type AuthErrorStatus, type AuthOrganization, type AuthSession, type AuthUser, type CanceledOrganizationInvitation, type CreateOrganizationMemberInvitationInput, type CreatedOrganizationMemberInvitation, type CreatedOrganizationTeam, type DriveCredential, type DriveCredentialInput, type DriveProvisioningAuthOptions, type DriveProvisioningCredential, type DriveRecipient, type DriveRecipientAuthOptions, type FinuevaDriveProvisioningAuth, type FinuevaDriveRecipientAuth, type FinuevaIdentityResolverAuth, FinuevaServerAuth, type IdentityResolverAuthOptions, type InvitationAcceptance, type OrganizationDisplay, type OrganizationInvitation, type OrganizationInvitationPage, type OrganizationMember, type OrganizationMemberAuthority, type OrganizationMemberPage, type OrganizationPage, type OrganizationPageInput, type OrganizationTeam, type OrganizationTeamDisplay, type OrganizationTeamMemberPage, type OrganizationTeamPage, type OrganizationWorkspaceSelection, type PersonalWorkspaceSelection, type ReceivedOrganizationInvitation, type ReceivedOrganizationInvitationPage, type ResentOrganizationInvitation, type ResolveDriveRecipientInput, type ResolveIdentityInput, type ResolvedIdentity, ServerAuthOptions, ServerInvitationAcceptance, ServerSignOutResult, ServerSocialIdTokenSession, type SocialIdTokenInput, type SocialIdTokenProvider, type UpdateOrganizationDisplayInput, type UpdateOrganizationTeamDisplayInput, type UserApiCredential, type UserApiCredentialInput, type UserApiIdentity, type UserApiVerifierOptions, type WorkspaceSelection, createDriveProvisioningAuth, createDriveRecipientAuth, createIdentityResolverAuth, createServerAuth, createUserApiVerifier };
|