@finueva/auth 0.16.1 → 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 +77 -1
- 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,6 +4532,13 @@ 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",
|
|
@@ -4622,13 +4693,14 @@ function createAuthClient(options) {
|
|
|
4622
4693
|
signalRefreshRequest = request;
|
|
4623
4694
|
}
|
|
4624
4695
|
function clearCredential() {
|
|
4696
|
+
userApiCredentials.clear();
|
|
4625
4697
|
credential = void 0;
|
|
4626
4698
|
credentialRequests.clear();
|
|
4627
4699
|
selectedWorkspaceKey = void 0;
|
|
4628
4700
|
credentialGeneration += 1;
|
|
4629
4701
|
}
|
|
4630
4702
|
function updateSession(session) {
|
|
4631
|
-
const unboundCredential = !sessionId && (credential || credentialRequests.size > 0);
|
|
4703
|
+
const unboundCredential = !sessionId && (credential || credentialRequests.size > 0 || userApiCredentials.hasAuthority());
|
|
4632
4704
|
const changedSession = sessionId === void 0 ? !sessionAuthorityObserved || session !== null : !session || session.id !== sessionId || session.user.id !== sessionUserId;
|
|
4633
4705
|
if (!session || unboundCredential || sessionId && (session.id !== sessionId || session.user.id !== sessionUserId)) clearCredential();
|
|
4634
4706
|
if (changedSession || recentAuthenticationStartAttempt && (recentAuthenticationStartAttempt.sessionId !== session?.id || recentAuthenticationStartAttempt.userId !== session?.user.id)) recentAuthenticationStartAttempt = void 0;
|
|
@@ -5197,6 +5269,10 @@ function createAuthClient(options) {
|
|
|
5197
5269
|
}));
|
|
5198
5270
|
},
|
|
5199
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
|
+
},
|
|
5200
5276
|
getDriveCredential(input) {
|
|
5201
5277
|
let workspace;
|
|
5202
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 };
|