@finueva/auth 0.11.0 → 0.11.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/README.md +36 -5
- package/dist/device.d.ts +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +215 -43
- package/dist/server.d.ts +1 -1
- package/dist/{types-BqpgLkQB.d.ts → types--G_Gwf2r.d.ts} +39 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
Use `@finueva/auth` to add Finueva sign-in, organization access, invitations, and Drive credentials to a browser, server, CLI, or native application.
|
|
4
4
|
|
|
5
|
-
The current published version is `0.
|
|
5
|
+
The current published version is `0.11.0`. The package is ESM-only. Node.js consumers require Node.js 22 or later. Other server runtimes must provide compatible Fetch, Web Crypto, URL, and Web Streams APIs. Its interface is Experimental until version `1.0.0`.
|
|
6
6
|
|
|
7
|
-
The
|
|
7
|
+
The platform-status and organization-authority methods below describe this repository's next package candidate. Published version `0.11.0` does not include them.
|
|
8
8
|
|
|
9
9
|
## Install
|
|
10
10
|
|
|
@@ -92,7 +92,9 @@ The browser owns the session cookie. The SDK does not expose or persist it.
|
|
|
92
92
|
| Invite an ordinary member | `createOrganizationMemberInvitation()` | `createOrganizationMemberInvitation()` | `createOrganizationMemberInvitation()` |
|
|
93
93
|
| Accept an invitation | `acceptInvitation()` | `acceptInvitation()` | Not available |
|
|
94
94
|
| Enroll a passkey | `addPasskey()` | Not available | Not available |
|
|
95
|
-
| Perform recent authentication |
|
|
95
|
+
| Perform recent authentication | Platform and organization action methods | Not available | Not available |
|
|
96
|
+
| Change manual roles or owners | Organization authority methods | Not available | Not available |
|
|
97
|
+
| Read current platform roles | `getPlatformStatus()` | Not available | Not available |
|
|
96
98
|
| Request Drive access | `getDriveCredential()` | `getDriveCredential()` | `getDriveCredential()` |
|
|
97
99
|
| End the current session | `signOut()` | `signOut()` | `revokeCurrentDevice()` |
|
|
98
100
|
|
|
@@ -129,7 +131,11 @@ Start one reviewed platform-role action before invoking passkey authentication:
|
|
|
129
131
|
await auth.startPlatformRoleChangeRecentAuthentication({
|
|
130
132
|
targetUserId: "user_01J8R7M6N5P4Q3S2T1",
|
|
131
133
|
requestedRoles: ["administrator", "investigator"],
|
|
132
|
-
|
|
134
|
+
expectedTargetRevision: 0,
|
|
135
|
+
expectedGlobalRevision: 0,
|
|
136
|
+
reasonCategory: "initial_bootstrap",
|
|
137
|
+
changeReference: "change_01J8R7M6N5P4Q3S2T1",
|
|
138
|
+
idempotencyKey: crypto.randomUUID(),
|
|
133
139
|
});
|
|
134
140
|
|
|
135
141
|
await auth.verifyRecentAuthenticationWithPasskey();
|
|
@@ -140,10 +146,35 @@ if (continuation.status === "ready") {
|
|
|
140
146
|
}
|
|
141
147
|
```
|
|
142
148
|
|
|
143
|
-
The maintained passkey client performs the WebAuthn ceremony for the pending action when a compatible authenticator is present. Auth binds the exact generated challenge to that action. The SDK returns only `pending` or `ready`. It does not expose the challenge, WebAuthn response, session, cookies, proof, or hashes. `ready` does not grant a platform role or reusable administration mode.
|
|
149
|
+
The maintained passkey client performs the WebAuthn ceremony for the pending action when a compatible authenticator is present. Auth binds the exact generated challenge to that action. The SDK returns only `pending` or `ready`. It does not expose the challenge, WebAuthn response, session, cookies, proof, or hashes. `ready` does not grant a platform role or reusable administration mode. Bootstrap approval consumes the proof atomically with its state transition.
|
|
150
|
+
|
|
151
|
+
Organization owner changes use the same ceremony. Pass the same input to the start and submit methods:
|
|
152
|
+
|
|
153
|
+
```ts
|
|
154
|
+
const change = {
|
|
155
|
+
requestedManualRole: "owner" as const,
|
|
156
|
+
expectedActorAuthorityRevision: 3,
|
|
157
|
+
expectedTargetAuthorityRevision: 1,
|
|
158
|
+
idempotencyKey: crypto.randomUUID(),
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
await auth.startOrganizationOwnerRoleChangeRecentAuthentication(organizationId, memberId, change);
|
|
162
|
+
await auth.verifyRecentAuthenticationWithPasskey();
|
|
163
|
+
await auth.changeOrganizationMemberManualRole(organizationId, memberId, change);
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
Atomic transfer similarly pairs `startOrganizationOwnershipTransferRecentAuthentication()` with `transferOrganizationOwnership()`. The input names distinct outgoing-owner and successor memberships, the outgoing owner's resulting `member` or `admin` role, all exact authority revisions, and one idempotency key. The SDK validates and sends one normalized request and never exposes the consumed proof.
|
|
144
167
|
|
|
145
168
|
If a start result is unavailable, call `startPlatformRoleChangeRecentAuthentication()` again with the same normalized input. The client reuses the current request nonce. A different start or observed account transition removes this local retry state. Only one start request can be active. An overlapping call returns `state_conflict` before network I/O. The SDK does not retry automatically.
|
|
146
169
|
|
|
170
|
+
Read the signed-in User's current effective platform roles on the exact Auth Origin:
|
|
171
|
+
|
|
172
|
+
```ts
|
|
173
|
+
const platform = await auth.getPlatformStatus();
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
The result contains `eligible`, `roles`, and `globalRevision`. Use it for display and mutation preparation only. Each platform operation checks current authority again. The browser SDK sends Auth-origin cookie credentials and an exact browser-generated `Origin`. It sends no `Authorization` header. Server and device clients do not expose this method.
|
|
177
|
+
|
|
147
178
|
## Request A Drive Credential
|
|
148
179
|
|
|
149
180
|
Request one short-lived credential for one workspace:
|
package/dist/device.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { C as OrganizationTeam, E as OrganizationTeamPage, G as UpdateProfileInput, H as SocialIdTokenProvider, I as ReceivedOrganizationInvitation, J as AuthErrorCode, L as ReceivedOrganizationInvitationPage, S as OrganizationPageInput, T as OrganizationTeamMemberPage, U as UpdateOrganizationDisplayInput, V as SocialIdTokenInput, W as UpdateOrganizationTeamDisplayInput, Y as AuthErrorStatus, _ as OrganizationInvitation, b as OrganizationMemberPage, d as CreatedOrganizationTeam, f as DriveCredential, g as OrganizationDisplay, l as CreateOrganizationMemberInvitationInput, o as AuthSession, p as DriveCredentialInput, q as AuthError, r as AuthOrganization, u as CreatedOrganizationMemberInvitation, v as OrganizationInvitationPage, w as OrganizationTeamDisplay, x as OrganizationPage, y as OrganizationMember } from "./types--G_Gwf2r.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 {
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { A as PlatformRole, B as
|
|
1
|
+
import { A as PlatformRole, B as SignInInput, C as OrganizationTeam, D as OrganizationWorkspaceSelection, E as OrganizationTeamPage, F as PlatformStatus, G as UpdateProfileInput, H as SocialIdTokenProvider, I as ReceivedOrganizationInvitation, J as AuthErrorCode, K as WorkspaceSelection, L as ReceivedOrganizationInvitationPage, M as PlatformRoleApproval, N as PlatformRoleChangeRecentAuthenticationInput, O as PersonalWorkspaceSelection, P as PlatformRoleFirstApproval, R as RecentAuthenticationStatus, S as OrganizationPageInput, T as OrganizationTeamMemberPage, U as UpdateOrganizationDisplayInput, V as SocialIdTokenInput, W as UpdateOrganizationTeamDisplayInput, Y as AuthErrorStatus, _ as OrganizationInvitation, a as AuthPersistenceDriver, b as OrganizationMemberPage, c as AuthUser, d as CreatedOrganizationTeam, f as DriveCredential, g as OrganizationDisplay, h as InvitationAcceptance, i as AuthPersistence, j as PlatformRoleApplied, k as PlatformBootstrapRoleChangeInput, l as CreateOrganizationMemberInvitationInput, m as FinuevaAuthClient, n as AuthClientOptions, o as AuthSession, p as DriveCredentialInput, q as AuthError, r as AuthOrganization, s as AuthState, t as AcceptInvitationInput, u as CreatedOrganizationMemberInvitation, v as OrganizationInvitationPage, w as OrganizationTeamDisplay, x as OrganizationPage, y as OrganizationMember, z as SendVerificationEmailInput } from "./types--G_Gwf2r.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 CreateOrganizationMemberInvitationInput, type CreatedOrganizationMemberInvitation, type CreatedOrganizationTeam, type DriveCredential, type DriveCredentialInput, type FinuevaAuthClient, type InvitationAcceptance, type OrganizationDisplay, type OrganizationInvitation, type OrganizationInvitationPage, type OrganizationMember, 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 ReceivedOrganizationInvitation, type ReceivedOrganizationInvitationPage, type RecentAuthenticationStatus, 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 CreateOrganizationMemberInvitationInput, type CreatedOrganizationMemberInvitation, type CreatedOrganizationTeam, type DriveCredential, type DriveCredentialInput, type FinuevaAuthClient, type InvitationAcceptance, type OrganizationDisplay, type OrganizationInvitation, type OrganizationInvitationPage, type OrganizationMember, 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 SendVerificationEmailInput, type SignInInput, type SocialIdTokenInput, type SocialIdTokenProvider, type UpdateOrganizationDisplayInput, type UpdateOrganizationTeamDisplayInput, type UpdateProfileInput, type WorkspaceSelection, createAuthClient };
|
package/dist/index.js
CHANGED
|
@@ -3322,6 +3322,88 @@ function normalizePlatformRoleChangeRecentAuthenticationInput(value) {
|
|
|
3322
3322
|
idempotencyKey: value.idempotencyKey
|
|
3323
3323
|
};
|
|
3324
3324
|
}
|
|
3325
|
+
function normalizeOrganizationManualRoleChangeInput(value) {
|
|
3326
|
+
if (!isObject(value) || Object.keys(value).sort().join(",") !== "expectedActorAuthorityRevision,expectedTargetAuthorityRevision,idempotencyKey,requestedManualRole") throw new TypeError("organization manual role input is invalid");
|
|
3327
|
+
if (value.requestedManualRole !== "owner" && value.requestedManualRole !== "admin" && value.requestedManualRole !== "member") throw new TypeError("requestedManualRole is invalid");
|
|
3328
|
+
const expectedActorAuthorityRevision = normalizeAuthorityRevision(value.expectedActorAuthorityRevision, "expectedActorAuthorityRevision");
|
|
3329
|
+
const expectedTargetAuthorityRevision = normalizeAuthorityRevision(value.expectedTargetAuthorityRevision, "expectedTargetAuthorityRevision", true);
|
|
3330
|
+
return {
|
|
3331
|
+
requestedManualRole: value.requestedManualRole,
|
|
3332
|
+
expectedActorAuthorityRevision,
|
|
3333
|
+
expectedTargetAuthorityRevision,
|
|
3334
|
+
idempotencyKey: normalizeAuthorityIdempotencyKey(value.idempotencyKey)
|
|
3335
|
+
};
|
|
3336
|
+
}
|
|
3337
|
+
function normalizeOrganizationOwnershipTransferInput(value) {
|
|
3338
|
+
if (!isObject(value) || Object.keys(value).sort().join(",") !== "expectedActorAuthorityRevision,expectedOutgoingOwnerAuthorityRevision,expectedSuccessorAuthorityRevision,idempotencyKey,outgoingOwnerMembershipId,outgoingOwnerRole,successorMembershipId") throw new TypeError("organization ownership transfer input is invalid");
|
|
3339
|
+
if (!isId(value.outgoingOwnerMembershipId) || !isId(value.successorMembershipId)) throw new TypeError("ownership transfer membership is invalid");
|
|
3340
|
+
if (value.outgoingOwnerMembershipId === value.successorMembershipId) throw new TypeError("ownership transfer memberships must differ");
|
|
3341
|
+
if (value.outgoingOwnerRole !== "admin" && value.outgoingOwnerRole !== "member") throw new TypeError("outgoingOwnerRole is invalid");
|
|
3342
|
+
return {
|
|
3343
|
+
outgoingOwnerMembershipId: value.outgoingOwnerMembershipId,
|
|
3344
|
+
successorMembershipId: value.successorMembershipId,
|
|
3345
|
+
outgoingOwnerRole: value.outgoingOwnerRole,
|
|
3346
|
+
expectedActorAuthorityRevision: normalizeAuthorityRevision(value.expectedActorAuthorityRevision, "expectedActorAuthorityRevision"),
|
|
3347
|
+
expectedOutgoingOwnerAuthorityRevision: normalizeAuthorityRevision(value.expectedOutgoingOwnerAuthorityRevision, "expectedOutgoingOwnerAuthorityRevision", true),
|
|
3348
|
+
expectedSuccessorAuthorityRevision: normalizeAuthorityRevision(value.expectedSuccessorAuthorityRevision, "expectedSuccessorAuthorityRevision", true),
|
|
3349
|
+
idempotencyKey: normalizeAuthorityIdempotencyKey(value.idempotencyKey)
|
|
3350
|
+
};
|
|
3351
|
+
}
|
|
3352
|
+
function normalizeOrganizationManualRoleChangeResult(value) {
|
|
3353
|
+
exact(value, [
|
|
3354
|
+
"status",
|
|
3355
|
+
"memberId",
|
|
3356
|
+
"manualRole",
|
|
3357
|
+
"role",
|
|
3358
|
+
"authorityRevision"
|
|
3359
|
+
]);
|
|
3360
|
+
if (value.status !== "applied") throw authorityUnavailable();
|
|
3361
|
+
return {
|
|
3362
|
+
status: "applied",
|
|
3363
|
+
...normalizeOrganizationAuthorityMemberOutcome(value, true)
|
|
3364
|
+
};
|
|
3365
|
+
}
|
|
3366
|
+
function normalizeOrganizationOwnershipTransferResult(value) {
|
|
3367
|
+
exact(value, [
|
|
3368
|
+
"status",
|
|
3369
|
+
"outgoingOwner",
|
|
3370
|
+
"successor"
|
|
3371
|
+
]);
|
|
3372
|
+
if (value.status !== "applied") throw authorityUnavailable();
|
|
3373
|
+
return {
|
|
3374
|
+
status: "applied",
|
|
3375
|
+
outgoingOwner: normalizeOrganizationAuthorityMemberOutcome(value.outgoingOwner),
|
|
3376
|
+
successor: normalizeOrganizationAuthorityMemberOutcome(value.successor)
|
|
3377
|
+
};
|
|
3378
|
+
}
|
|
3379
|
+
function normalizeOrganizationAuthorityMemberOutcome(value, includesStatus = false) {
|
|
3380
|
+
exact(value, [
|
|
3381
|
+
"memberId",
|
|
3382
|
+
"manualRole",
|
|
3383
|
+
"role",
|
|
3384
|
+
"authorityRevision",
|
|
3385
|
+
...includesStatus ? ["status"] : []
|
|
3386
|
+
]);
|
|
3387
|
+
if (!isId(value.memberId) || value.manualRole !== "owner" && value.manualRole !== "admin" && value.manualRole !== "member" || value.role !== "owner" && value.role !== "admin" && value.role !== "member") throw authorityUnavailable();
|
|
3388
|
+
return {
|
|
3389
|
+
memberId: value.memberId,
|
|
3390
|
+
manualRole: value.manualRole,
|
|
3391
|
+
role: value.role,
|
|
3392
|
+
authorityRevision: normalizeAuthorityResultRevision(value.authorityRevision)
|
|
3393
|
+
};
|
|
3394
|
+
}
|
|
3395
|
+
function normalizeAuthorityRevision(value, name, incremented = false) {
|
|
3396
|
+
if (!Number.isSafeInteger(value) || value < 0 || value >= Number.MAX_SAFE_INTEGER - (incremented ? 1 : 0)) throw new TypeError(`${name} is invalid`);
|
|
3397
|
+
return value;
|
|
3398
|
+
}
|
|
3399
|
+
function normalizeAuthorityResultRevision(value) {
|
|
3400
|
+
if (!Number.isSafeInteger(value) || value < 0 || value >= Number.MAX_SAFE_INTEGER) throw authorityUnavailable();
|
|
3401
|
+
return value;
|
|
3402
|
+
}
|
|
3403
|
+
function normalizeAuthorityIdempotencyKey(value) {
|
|
3404
|
+
if (typeof value !== "string" || !/^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/.test(value)) throw new TypeError("idempotencyKey is invalid");
|
|
3405
|
+
return value;
|
|
3406
|
+
}
|
|
3325
3407
|
function normalizePlatformBootstrapRoleChangeInput(value) {
|
|
3326
3408
|
const request = normalizePlatformRoleChangeRecentAuthenticationInput(value);
|
|
3327
3409
|
if (request.reasonCategory !== "initial_bootstrap" || !request.requestedRoles.includes("administrator")) throw new TypeError("platform first approval input is invalid");
|
|
@@ -3354,6 +3436,21 @@ function normalizePlatformRoleApproval(value) {
|
|
|
3354
3436
|
roles: []
|
|
3355
3437
|
};
|
|
3356
3438
|
}
|
|
3439
|
+
function normalizePlatformStatus(value) {
|
|
3440
|
+
exact(value, [
|
|
3441
|
+
"eligible",
|
|
3442
|
+
"globalRevision",
|
|
3443
|
+
"roles"
|
|
3444
|
+
]);
|
|
3445
|
+
if (typeof value.eligible !== "boolean") throw authorityUnavailable();
|
|
3446
|
+
if (!Number.isSafeInteger(value.globalRevision) || value.globalRevision < 0 || value.globalRevision >= Number.MAX_SAFE_INTEGER) throw authorityUnavailable();
|
|
3447
|
+
if (!Array.isArray(value.roles) || !(value.roles.length === 0 || value.roles.length === 1 && (value.roles[0] === "administrator" || value.roles[0] === "investigator") || value.roles.length === 2 && value.roles[0] === "administrator" && value.roles[1] === "investigator") || !value.eligible && value.roles.length !== 0) throw authorityUnavailable();
|
|
3448
|
+
return {
|
|
3449
|
+
eligible: value.eligible,
|
|
3450
|
+
globalRevision: value.globalRevision,
|
|
3451
|
+
roles: value.roles
|
|
3452
|
+
};
|
|
3453
|
+
}
|
|
3357
3454
|
function normalizeRecentAuthenticationStatus(value) {
|
|
3358
3455
|
exact(value, ["status"]);
|
|
3359
3456
|
if (value.status !== "pending" && value.status !== "ready") throw authorityUnavailable();
|
|
@@ -4354,6 +4451,9 @@ function createAuthClient(options) {
|
|
|
4354
4451
|
let selectedWorkspaceKey;
|
|
4355
4452
|
let credentialGeneration = 0;
|
|
4356
4453
|
let authorityGeneration = 0;
|
|
4454
|
+
let platformStatusReadEpoch = 0;
|
|
4455
|
+
let sessionAuthorityEpoch = 0;
|
|
4456
|
+
let sessionAuthorityObserved = false;
|
|
4357
4457
|
let recentAuthenticationBrowserToken;
|
|
4358
4458
|
let recentAuthenticationStartAttempt;
|
|
4359
4459
|
let recentAuthenticationStartRequest;
|
|
@@ -4479,9 +4579,11 @@ function createAuthClient(options) {
|
|
|
4479
4579
|
}
|
|
4480
4580
|
function updateSession(session) {
|
|
4481
4581
|
const unboundCredential = !sessionId && (credential || credentialRequests.size > 0);
|
|
4482
|
-
const changedSession = !
|
|
4582
|
+
const changedSession = sessionId === void 0 ? !sessionAuthorityObserved || session !== null : !session || session.id !== sessionId || session.user.id !== sessionUserId;
|
|
4483
4583
|
if (!session || unboundCredential || sessionId && (session.id !== sessionId || session.user.id !== sessionUserId)) clearCredential();
|
|
4484
4584
|
if (changedSession || recentAuthenticationStartAttempt && (recentAuthenticationStartAttempt.sessionId !== session?.id || recentAuthenticationStartAttempt.userId !== session?.user.id)) recentAuthenticationStartAttempt = void 0;
|
|
4585
|
+
if (changedSession) sessionAuthorityEpoch += 1;
|
|
4586
|
+
sessionAuthorityObserved = true;
|
|
4485
4587
|
sessionId = session?.id;
|
|
4486
4588
|
sessionUserId = session?.user.id;
|
|
4487
4589
|
return session;
|
|
@@ -4631,52 +4733,89 @@ function createAuthClient(options) {
|
|
|
4631
4733
|
function assertRecentAuthenticationOrigin() {
|
|
4632
4734
|
if (appOrigin !== authOrigin) throw new TypeError("recent authentication requires the exact Auth Origin");
|
|
4633
4735
|
}
|
|
4736
|
+
function assertPlatformAdministrationOrigin() {
|
|
4737
|
+
if (appOrigin !== authOrigin) throw new TypeError("platform administration requires the exact Auth Origin");
|
|
4738
|
+
}
|
|
4739
|
+
async function startRecentAuthentication(body) {
|
|
4740
|
+
assertRecentAuthenticationOrigin();
|
|
4741
|
+
if (signOutRequest || activeAccountMutationGeneration !== void 0 || invitationRequest) throw new AuthError("state_conflict", 409);
|
|
4742
|
+
if (recentAuthenticationStartRequest) throw new AuthError("state_conflict", 409);
|
|
4743
|
+
const generation = authorityGeneration;
|
|
4744
|
+
recentAuthenticationBrowserToken ??= createOpaqueToken();
|
|
4745
|
+
const normalizedInput = JSON.stringify(body);
|
|
4746
|
+
const attempt = recentAuthenticationStartAttempt?.input === normalizedInput ? recentAuthenticationStartAttempt : {
|
|
4747
|
+
input: normalizedInput,
|
|
4748
|
+
requestToken: createOpaqueToken(),
|
|
4749
|
+
sessionId,
|
|
4750
|
+
userId: sessionUserId
|
|
4751
|
+
};
|
|
4752
|
+
recentAuthenticationStartAttempt = attempt;
|
|
4753
|
+
const request = (async () => {
|
|
4754
|
+
try {
|
|
4755
|
+
const value = await requestJson(joinURL(authOrigin, "api/v1/auth/recent-authentication"), {
|
|
4756
|
+
fetch: fetchImpl,
|
|
4757
|
+
timeoutMs,
|
|
4758
|
+
method: "POST",
|
|
4759
|
+
headers: {
|
|
4760
|
+
"content-type": "application/json",
|
|
4761
|
+
[RECENT_AUTHENTICATION_BROWSER_HEADER]: recentAuthenticationBrowserToken,
|
|
4762
|
+
[RECENT_AUTHENTICATION_REQUEST_HEADER]: attempt.requestToken
|
|
4763
|
+
},
|
|
4764
|
+
body,
|
|
4765
|
+
mapError: fromRecentAuthenticationError
|
|
4766
|
+
});
|
|
4767
|
+
if (generation !== authorityGeneration) throw new AuthError("state_conflict", 409);
|
|
4768
|
+
const status = normalizeRecentAuthenticationStatus(value);
|
|
4769
|
+
if (recentAuthenticationStartAttempt === attempt) recentAuthenticationStartAttempt = void 0;
|
|
4770
|
+
return status;
|
|
4771
|
+
} catch (error) {
|
|
4772
|
+
if (recentAuthenticationStartAttempt === attempt && (!(error instanceof AuthError) || error.code !== "identity_authority_unavailable")) recentAuthenticationStartAttempt = void 0;
|
|
4773
|
+
throw error;
|
|
4774
|
+
}
|
|
4775
|
+
})();
|
|
4776
|
+
recentAuthenticationStartRequest = request;
|
|
4777
|
+
try {
|
|
4778
|
+
return await request;
|
|
4779
|
+
} finally {
|
|
4780
|
+
if (recentAuthenticationStartRequest === request) recentAuthenticationStartRequest = void 0;
|
|
4781
|
+
}
|
|
4782
|
+
}
|
|
4634
4783
|
return {
|
|
4635
4784
|
_type: "browser",
|
|
4636
|
-
async
|
|
4637
|
-
|
|
4638
|
-
const body = normalizePlatformRoleChangeRecentAuthenticationInput(input);
|
|
4785
|
+
async getPlatformStatus() {
|
|
4786
|
+
assertPlatformAdministrationOrigin();
|
|
4639
4787
|
if (signOutRequest || activeAccountMutationGeneration !== void 0 || invitationRequest) throw new AuthError("state_conflict", 409);
|
|
4640
|
-
if (recentAuthenticationStartRequest) throw new AuthError("state_conflict", 409);
|
|
4641
4788
|
const generation = authorityGeneration;
|
|
4642
|
-
|
|
4643
|
-
const
|
|
4644
|
-
const
|
|
4645
|
-
|
|
4646
|
-
|
|
4647
|
-
|
|
4648
|
-
|
|
4649
|
-
|
|
4650
|
-
|
|
4651
|
-
|
|
4652
|
-
|
|
4653
|
-
|
|
4654
|
-
|
|
4655
|
-
|
|
4656
|
-
|
|
4657
|
-
|
|
4658
|
-
|
|
4659
|
-
|
|
4660
|
-
|
|
4661
|
-
|
|
4662
|
-
|
|
4663
|
-
|
|
4664
|
-
|
|
4665
|
-
|
|
4666
|
-
|
|
4667
|
-
|
|
4668
|
-
|
|
4669
|
-
|
|
4670
|
-
|
|
4671
|
-
|
|
4672
|
-
}
|
|
4673
|
-
})();
|
|
4674
|
-
recentAuthenticationStartRequest = request;
|
|
4675
|
-
try {
|
|
4676
|
-
return await request;
|
|
4677
|
-
} finally {
|
|
4678
|
-
if (recentAuthenticationStartRequest === request) recentAuthenticationStartRequest = void 0;
|
|
4679
|
-
}
|
|
4789
|
+
const readEpoch = ++platformStatusReadEpoch;
|
|
4790
|
+
const sessionEpoch = sessionAuthorityEpoch;
|
|
4791
|
+
const value = await requestJson(joinURL(authOrigin, "api/v1/auth/platform/status"), {
|
|
4792
|
+
fetch: fetchImpl,
|
|
4793
|
+
timeoutMs,
|
|
4794
|
+
method: "POST",
|
|
4795
|
+
headers: { "content-type": "application/json" },
|
|
4796
|
+
body: {},
|
|
4797
|
+
mapError: fromPlatformAdministrationError
|
|
4798
|
+
});
|
|
4799
|
+
if (generation !== authorityGeneration || readEpoch !== platformStatusReadEpoch || sessionEpoch !== sessionAuthorityEpoch) throw new AuthError("state_conflict", 409);
|
|
4800
|
+
return normalizePlatformStatus(value);
|
|
4801
|
+
},
|
|
4802
|
+
async startPlatformRoleChangeRecentAuthentication(input) {
|
|
4803
|
+
return startRecentAuthentication(normalizePlatformRoleChangeRecentAuthenticationInput(input));
|
|
4804
|
+
},
|
|
4805
|
+
async startOrganizationOwnerRoleChangeRecentAuthentication(organizationId, targetMembershipId, input) {
|
|
4806
|
+
return startRecentAuthentication({
|
|
4807
|
+
action: "organization_owner_role_change",
|
|
4808
|
+
organizationId: normalizeIdInput(organizationId),
|
|
4809
|
+
targetMembershipId: normalizeIdInput(targetMembershipId),
|
|
4810
|
+
...normalizeOrganizationManualRoleChangeInput(input)
|
|
4811
|
+
});
|
|
4812
|
+
},
|
|
4813
|
+
async startOrganizationOwnershipTransferRecentAuthentication(organizationId, input) {
|
|
4814
|
+
return startRecentAuthentication({
|
|
4815
|
+
action: "organization_ownership_transfer",
|
|
4816
|
+
organizationId: normalizeIdInput(organizationId),
|
|
4817
|
+
...normalizeOrganizationOwnershipTransferInput(input)
|
|
4818
|
+
});
|
|
4680
4819
|
},
|
|
4681
4820
|
async approveBootstrapPlatformRoleChange(input) {
|
|
4682
4821
|
assertRecentAuthenticationOrigin();
|
|
@@ -4837,6 +4976,39 @@ function createAuthClient(options) {
|
|
|
4837
4976
|
if (generation !== authorityGeneration) throw new AuthError("state_conflict", 409);
|
|
4838
4977
|
return normalizeOrganizationTeamDisplay(value);
|
|
4839
4978
|
},
|
|
4979
|
+
async changeOrganizationMemberManualRole(organizationId, targetMembershipId, input) {
|
|
4980
|
+
const organization = normalizeIdInput(organizationId);
|
|
4981
|
+
const target = normalizeIdInput(targetMembershipId);
|
|
4982
|
+
const body = normalizeOrganizationManualRoleChangeInput(input);
|
|
4983
|
+
if (signOutRequest || activeAccountMutationGeneration !== void 0 || invitationRequest) throw new AuthError("state_conflict", 409);
|
|
4984
|
+
const generation = authorityGeneration;
|
|
4985
|
+
const value = await requestJson(joinURL(authOrigin, "api/v1/auth/organizations", organization, "members", target, "manual-role"), {
|
|
4986
|
+
fetch: fetchImpl,
|
|
4987
|
+
timeoutMs,
|
|
4988
|
+
method: "POST",
|
|
4989
|
+
headers: { "content-type": "application/json" },
|
|
4990
|
+
body,
|
|
4991
|
+
mapError: fromOrganizationMutationAuthorityError
|
|
4992
|
+
});
|
|
4993
|
+
if (generation !== authorityGeneration) throw new AuthError("state_conflict", 409);
|
|
4994
|
+
return normalizeOrganizationManualRoleChangeResult(value);
|
|
4995
|
+
},
|
|
4996
|
+
async transferOrganizationOwnership(organizationId, input) {
|
|
4997
|
+
const organization = normalizeIdInput(organizationId);
|
|
4998
|
+
const body = normalizeOrganizationOwnershipTransferInput(input);
|
|
4999
|
+
if (signOutRequest || activeAccountMutationGeneration !== void 0 || invitationRequest) throw new AuthError("state_conflict", 409);
|
|
5000
|
+
const generation = authorityGeneration;
|
|
5001
|
+
const value = await requestJson(joinURL(authOrigin, "api/v1/auth/organizations", organization, "ownership-transfer"), {
|
|
5002
|
+
fetch: fetchImpl,
|
|
5003
|
+
timeoutMs,
|
|
5004
|
+
method: "POST",
|
|
5005
|
+
headers: { "content-type": "application/json" },
|
|
5006
|
+
body,
|
|
5007
|
+
mapError: fromOrganizationMutationAuthorityError
|
|
5008
|
+
});
|
|
5009
|
+
if (generation !== authorityGeneration) throw new AuthError("state_conflict", 409);
|
|
5010
|
+
return normalizeOrganizationOwnershipTransferResult(value);
|
|
5011
|
+
},
|
|
4840
5012
|
async listOrganizationMembers(organizationId, input) {
|
|
4841
5013
|
return organizationRead(`${normalizeIdInput(organizationId)}/members`, input, normalizeOrganizationMembers);
|
|
4842
5014
|
},
|
package/dist/server.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { C as OrganizationTeam, D as OrganizationWorkspaceSelection, E as OrganizationTeamPage, H as SocialIdTokenProvider, I as ReceivedOrganizationInvitation, J as AuthErrorCode, K as WorkspaceSelection, L as ReceivedOrganizationInvitationPage, O as PersonalWorkspaceSelection, S as OrganizationPageInput, T as OrganizationTeamMemberPage, U as UpdateOrganizationDisplayInput, V as SocialIdTokenInput, W as UpdateOrganizationTeamDisplayInput, Y as AuthErrorStatus, _ as OrganizationInvitation, b as OrganizationMemberPage, c as AuthUser, d as CreatedOrganizationTeam, f as DriveCredential, g as OrganizationDisplay, h as InvitationAcceptance, l as CreateOrganizationMemberInvitationInput, o as AuthSession, p as DriveCredentialInput, q as AuthError, r as AuthOrganization, t as AcceptInvitationInput, u as CreatedOrganizationMemberInvitation, v as OrganizationInvitationPage, w as OrganizationTeamDisplay, x as OrganizationPage, y as OrganizationMember } from "./types--G_Gwf2r.js";
|
|
2
2
|
//#region src/server.d.ts
|
|
3
3
|
interface ServerAuthOptions {
|
|
4
4
|
authOrigin: string;
|
|
@@ -194,6 +194,11 @@ interface DriveCredentialInput {
|
|
|
194
194
|
forceRefresh?: boolean;
|
|
195
195
|
}
|
|
196
196
|
type PlatformRole = "administrator" | "investigator";
|
|
197
|
+
interface PlatformStatus {
|
|
198
|
+
eligible: boolean;
|
|
199
|
+
globalRevision: number;
|
|
200
|
+
roles: PlatformRole[];
|
|
201
|
+
}
|
|
197
202
|
interface PlatformRoleChangeRecentAuthenticationInput {
|
|
198
203
|
targetUserId: string;
|
|
199
204
|
requestedRoles: PlatformRole[];
|
|
@@ -225,6 +230,34 @@ type PlatformRoleApproval = PlatformRoleFirstApproval | PlatformRoleApplied;
|
|
|
225
230
|
interface RecentAuthenticationStatus {
|
|
226
231
|
status: "pending" | "ready";
|
|
227
232
|
}
|
|
233
|
+
type OrganizationManualRole = "owner" | "admin" | "member";
|
|
234
|
+
interface OrganizationManualRoleChangeInput {
|
|
235
|
+
requestedManualRole: OrganizationManualRole;
|
|
236
|
+
expectedActorAuthorityRevision: number;
|
|
237
|
+
expectedTargetAuthorityRevision: number;
|
|
238
|
+
idempotencyKey: string;
|
|
239
|
+
}
|
|
240
|
+
interface OrganizationManualRoleChangeResult {
|
|
241
|
+
status: "applied";
|
|
242
|
+
memberId: string;
|
|
243
|
+
manualRole: OrganizationManualRole;
|
|
244
|
+
role: OrganizationManualRole;
|
|
245
|
+
authorityRevision: number;
|
|
246
|
+
}
|
|
247
|
+
interface OrganizationOwnershipTransferInput {
|
|
248
|
+
outgoingOwnerMembershipId: string;
|
|
249
|
+
successorMembershipId: string;
|
|
250
|
+
outgoingOwnerRole: "admin" | "member";
|
|
251
|
+
expectedActorAuthorityRevision: number;
|
|
252
|
+
expectedOutgoingOwnerAuthorityRevision: number;
|
|
253
|
+
expectedSuccessorAuthorityRevision: number;
|
|
254
|
+
idempotencyKey: string;
|
|
255
|
+
}
|
|
256
|
+
interface OrganizationOwnershipTransferResult {
|
|
257
|
+
status: "applied";
|
|
258
|
+
outgoingOwner: Omit<OrganizationManualRoleChangeResult, "status">;
|
|
259
|
+
successor: Omit<OrganizationManualRoleChangeResult, "status">;
|
|
260
|
+
}
|
|
228
261
|
interface AuthClientOptions {
|
|
229
262
|
authOrigin: string;
|
|
230
263
|
appOrigin: string;
|
|
@@ -235,7 +268,10 @@ interface AuthClientOptions {
|
|
|
235
268
|
}
|
|
236
269
|
interface FinuevaAuthClient {
|
|
237
270
|
readonly _type: "browser";
|
|
271
|
+
getPlatformStatus(): Promise<PlatformStatus>;
|
|
238
272
|
startPlatformRoleChangeRecentAuthentication(input: PlatformRoleChangeRecentAuthenticationInput): Promise<RecentAuthenticationStatus>;
|
|
273
|
+
startOrganizationOwnerRoleChangeRecentAuthentication(organizationId: string, targetMembershipId: string, input: OrganizationManualRoleChangeInput): Promise<RecentAuthenticationStatus>;
|
|
274
|
+
startOrganizationOwnershipTransferRecentAuthentication(organizationId: string, input: OrganizationOwnershipTransferInput): Promise<RecentAuthenticationStatus>;
|
|
239
275
|
approveBootstrapPlatformRoleChange(input: PlatformBootstrapRoleChangeInput): Promise<PlatformRoleApproval>;
|
|
240
276
|
addPasskey(): Promise<void>;
|
|
241
277
|
verifyRecentAuthenticationWithPasskey(): Promise<void>;
|
|
@@ -248,6 +284,8 @@ interface FinuevaAuthClient {
|
|
|
248
284
|
createOrganizationMemberInvitation(organizationId: string, input: CreateOrganizationMemberInvitationInput): Promise<CreatedOrganizationMemberInvitation>;
|
|
249
285
|
updateOrganizationDisplay(organizationId: string, input: UpdateOrganizationDisplayInput): Promise<OrganizationDisplay>;
|
|
250
286
|
updateOrganizationTeamDisplay(organizationId: string, teamId: string, input: UpdateOrganizationTeamDisplayInput): Promise<OrganizationTeamDisplay>;
|
|
287
|
+
changeOrganizationMemberManualRole(organizationId: string, targetMembershipId: string, input: OrganizationManualRoleChangeInput): Promise<OrganizationManualRoleChangeResult>;
|
|
288
|
+
transferOrganizationOwnership(organizationId: string, input: OrganizationOwnershipTransferInput): Promise<OrganizationOwnershipTransferResult>;
|
|
251
289
|
listOrganizationMembers(organizationId: string, input?: OrganizationPageInput): Promise<OrganizationMemberPage>;
|
|
252
290
|
listOrganizationTeams(organizationId: string, input?: OrganizationPageInput): Promise<OrganizationTeamPage>;
|
|
253
291
|
listOrganizationTeamMembers(organizationId: string, teamId: string, input?: OrganizationPageInput): Promise<OrganizationTeamMemberPage>;
|
|
@@ -269,4 +307,4 @@ interface FinuevaAuthClient {
|
|
|
269
307
|
onSessionChange(listener: (session: AuthSession | null) => void): () => void;
|
|
270
308
|
}
|
|
271
309
|
//#endregion
|
|
272
|
-
export { PlatformRole as A,
|
|
310
|
+
export { PlatformRole as A, SignInInput as B, OrganizationTeam as C, OrganizationWorkspaceSelection as D, OrganizationTeamPage as E, PlatformStatus as F, UpdateProfileInput as G, SocialIdTokenProvider as H, ReceivedOrganizationInvitation as I, AuthErrorCode as J, WorkspaceSelection as K, ReceivedOrganizationInvitationPage as L, PlatformRoleApproval as M, PlatformRoleChangeRecentAuthenticationInput as N, PersonalWorkspaceSelection as O, PlatformRoleFirstApproval as P, RecentAuthenticationStatus as R, OrganizationPageInput as S, OrganizationTeamMemberPage as T, UpdateOrganizationDisplayInput as U, SocialIdTokenInput as V, UpdateOrganizationTeamDisplayInput as W, AuthErrorStatus as Y, OrganizationInvitation as _, AuthPersistenceDriver as a, OrganizationMemberPage as b, AuthUser as c, CreatedOrganizationTeam as d, DriveCredential as f, OrganizationDisplay as g, InvitationAcceptance as h, AuthPersistence as i, PlatformRoleApplied as j, PlatformBootstrapRoleChangeInput as k, CreateOrganizationMemberInvitationInput as l, FinuevaAuthClient as m, AuthClientOptions as n, AuthSession as o, DriveCredentialInput as p, AuthError as q, AuthOrganization as r, AuthState as s, AcceptInvitationInput as t, CreatedOrganizationMemberInvitation as u, OrganizationInvitationPage as v, OrganizationTeamDisplay as w, OrganizationPage as x, OrganizationMember as y, SendVerificationEmailInput as z };
|