@finueva/auth 0.9.0 → 0.10.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/README.md +73 -2
- package/dist/device.d.ts +6 -2
- package/dist/device.js +189 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +148 -0
- package/dist/server.d.ts +6 -2
- package/dist/server.js +154 -0
- package/dist/{types-B67VIvTQ.d.ts → types-Byw9JQwL.d.ts} +28 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -7,12 +7,14 @@ Use it to:
|
|
|
7
7
|
- sign users in with email and password;
|
|
8
8
|
- read the current session;
|
|
9
9
|
- manage profile and password details;
|
|
10
|
-
-
|
|
10
|
+
- read organizations, create ordinary teams, replace display data, and accept invitations;
|
|
11
11
|
- request short-lived Drive credentials;
|
|
12
12
|
- authenticate CLIs and native applications.
|
|
13
13
|
|
|
14
14
|
The package is ESM-only and has no runtime dependencies. Its API is experimental while the package is below `1.0.0`.
|
|
15
15
|
|
|
16
|
+
Sections marked **Unreleased** describe repository source and are not available in the currently published `@finueva/auth@0.9.0` package.
|
|
17
|
+
|
|
16
18
|
## Install
|
|
17
19
|
|
|
18
20
|
```sh
|
|
@@ -203,6 +205,45 @@ insert at or before the cursor can be absent, an insert after it can appear once
|
|
|
203
205
|
update, status change, or expiry can change later pages. Restart pagination when you need a current
|
|
204
206
|
view.
|
|
205
207
|
|
|
208
|
+
### Create A Team
|
|
209
|
+
|
|
210
|
+
**Unreleased:** this method will ship in a later package version and is not in `@finueva/auth@0.9.0`.
|
|
211
|
+
|
|
212
|
+
```ts
|
|
213
|
+
const idempotencyKey = crypto.randomUUID();
|
|
214
|
+
const team = await auth.createOrganizationTeam("org_01J8R7M6N5P4Q3S2T1", "Platform Engineering", idempotencyKey);
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
The name and caller-owned idempotency key must each contain from 1 through 255 UTF-8 bytes. Use a
|
|
218
|
+
new key for each intended team. If a response is lost, send the same organization ID, name, and key
|
|
219
|
+
again. Auth returns the original creation result for a completed same-key request, even if a later
|
|
220
|
+
operation changed the team display. A conflicting or unresolved same-key request returns
|
|
221
|
+
`state_conflict`. The SDK never retries automatically.
|
|
222
|
+
|
|
223
|
+
For an ordinary organization, a current effective owner or administrator can use the cookie or
|
|
224
|
+
bearer lane. For a managed organization, a current manual owner or manual administrator must use the
|
|
225
|
+
cookie lane. The method creates only an ordinary team.
|
|
226
|
+
|
|
227
|
+
### Create A Member Invitation
|
|
228
|
+
|
|
229
|
+
**Unreleased:** this method will ship in a later package version and is not in `@finueva/auth@0.9.0`.
|
|
230
|
+
|
|
231
|
+
```ts
|
|
232
|
+
const invitation = await auth.createOrganizationMemberInvitation("org_01J8R7M6N5P4Q3S2T1", {
|
|
233
|
+
email: "member@example.com",
|
|
234
|
+
teamIds: ["team_01J8R7M6N5P4Q3S2T1"],
|
|
235
|
+
idempotencyKey: crypto.randomUUID(),
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
console.log(invitation.id, invitation.expiresAt);
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
The SDK trims and lowercases the email address. The email address can contain no more than 320 UTF-8 bytes. `teamIds` is optional and can contain no more than 100 unique ordinary team IDs. The caller-owned idempotency key must contain from 1 through 255 UTF-8 bytes.
|
|
242
|
+
|
|
243
|
+
Use a new key for each intended invitation. If a response is lost, send the same organization ID and input again. The method returns only the invitation ID and expiry. It does not report email delivery. The SDK never retries automatically.
|
|
244
|
+
|
|
245
|
+
For an ordinary organization, a current effective owner or administrator can use the cookie or bearer lane. Managed organizations are denied.
|
|
246
|
+
|
|
206
247
|
### Accept An Invitation
|
|
207
248
|
|
|
208
249
|
```ts
|
|
@@ -213,6 +254,36 @@ const result = await auth.acceptInvitation({
|
|
|
213
254
|
console.log(result.organizationId);
|
|
214
255
|
```
|
|
215
256
|
|
|
257
|
+
### Replace Organization Display
|
|
258
|
+
|
|
259
|
+
```ts
|
|
260
|
+
const display = await auth.updateOrganizationDisplay("org_01J8R7M6N5P4Q3S2T1", {
|
|
261
|
+
name: "Example Group",
|
|
262
|
+
slug: "example-group",
|
|
263
|
+
logo: null,
|
|
264
|
+
});
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
Send all three fields. `name` and `slug` can contain no more than 255 UTF-8 bytes. Use `logo: null` to remove the logo. A non-null logo must be an exact canonical HTTPS URL of no more than 2048 UTF-8 bytes. The method supports manual owners and manual administrators of ordinary organizations. Provider-only administrators are denied. It does not update metadata, lifecycle, membership, teams, invitations, or active-organization state.
|
|
268
|
+
|
|
269
|
+
Browser and cookie-based server calls require the exact configured application Origin. The SDK reports a denied or missing Origin as `request_origin_denied`. Other organization authority denials use `access_denied`.
|
|
270
|
+
|
|
271
|
+
The method does not retry. If a response is lost, submit the same complete desired state again. Concurrent different updates use last-write-wins behavior.
|
|
272
|
+
|
|
273
|
+
### Replace Team Display
|
|
274
|
+
|
|
275
|
+
**Unreleased:** this method will ship in a later package version and is not in `@finueva/auth@0.9.0`.
|
|
276
|
+
|
|
277
|
+
```ts
|
|
278
|
+
const display = await auth.updateOrganizationTeamDisplay("org_01J8R7M6N5P4Q3S2T1", "team_01J8R7M6N5P4Q3S2T1", {
|
|
279
|
+
name: "Platform Engineering",
|
|
280
|
+
});
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
Send the complete `name`. It can contain no more than 255 UTF-8 bytes. For an ordinary organization, a current effective owner or administrator can use the cookie or bearer lane. For a managed organization, a current manual owner or manual administrator must use the cookie lane. Managed teams are denied.
|
|
284
|
+
|
|
285
|
+
The method does not retry. If a response is lost, submit the same complete desired name again. Concurrent different updates use last-write-wins behavior.
|
|
286
|
+
|
|
216
287
|
### Sign Out
|
|
217
288
|
|
|
218
289
|
```ts
|
|
@@ -469,7 +540,7 @@ The SDK does not automatically retry requests.
|
|
|
469
540
|
- Browser snapshots and bearer authorization values are limited to 16 KiB.
|
|
470
541
|
- Organization lists fail closed at 100 records.
|
|
471
542
|
- Organization Drive context supports at most 50 current teams.
|
|
472
|
-
- Account deletion and organization management are not exposed.
|
|
543
|
+
- Ordinary-organization display replacement is the only organization mutation in `@finueva/auth@0.9.0`. Unreleased source also exposes ordinary-team creation and display replacement. Account deletion and other organization management are not exposed.
|
|
473
544
|
- Cross-root SSO and custom refresh tokens are not implemented.
|
|
474
545
|
- Hosted mobile transport and operating-system vault qualification are incomplete.
|
|
475
546
|
- Production support gates are not complete.
|
package/dist/device.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { A as
|
|
1
|
+
import { A as ReceivedOrganizationInvitationPage, B as AuthErrorCode, C as OrganizationTeam, E as OrganizationTeamPage, F as UpdateOrganizationDisplayInput, I as UpdateOrganizationTeamDisplayInput, L as UpdateProfileInput, N as SocialIdTokenInput, P as SocialIdTokenProvider, S as OrganizationPageInput, T as OrganizationTeamMemberPage, V as AuthErrorStatus, _ as OrganizationInvitation, b as OrganizationMemberPage, d as CreatedOrganizationTeam, f as DriveCredential, g as OrganizationDisplay, k as ReceivedOrganizationInvitation, l as CreateOrganizationMemberInvitationInput, o as AuthSession, p as DriveCredentialInput, r as AuthOrganization, u as CreatedOrganizationMemberInvitation, v as OrganizationInvitationPage, w as OrganizationTeamDisplay, x as OrganizationPage, y as OrganizationMember, z as AuthError } from "./types-Byw9JQwL.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 {
|
|
@@ -45,6 +45,10 @@ interface DeviceAuthClient {
|
|
|
45
45
|
getSession(): Promise<AuthSession | null>;
|
|
46
46
|
listOrganizations(input?: OrganizationPageInput): Promise<OrganizationPage>;
|
|
47
47
|
getOrganization(organizationId: string): Promise<AuthOrganization>;
|
|
48
|
+
createOrganizationTeam(organizationId: string, name: string, idempotencyKey: string): Promise<CreatedOrganizationTeam>;
|
|
49
|
+
createOrganizationMemberInvitation(organizationId: string, input: CreateOrganizationMemberInvitationInput): Promise<CreatedOrganizationMemberInvitation>;
|
|
50
|
+
updateOrganizationDisplay(organizationId: string, input: UpdateOrganizationDisplayInput): Promise<OrganizationDisplay>;
|
|
51
|
+
updateOrganizationTeamDisplay(organizationId: string, teamId: string, input: UpdateOrganizationTeamDisplayInput): Promise<OrganizationTeamDisplay>;
|
|
48
52
|
listOrganizationMembers(organizationId: string, input?: OrganizationPageInput): Promise<OrganizationMemberPage>;
|
|
49
53
|
listOrganizationTeams(organizationId: string, input?: OrganizationPageInput): Promise<OrganizationTeamPage>;
|
|
50
54
|
listOrganizationTeamMembers(organizationId: string, teamId: string, input?: OrganizationPageInput): Promise<OrganizationTeamMemberPage>;
|
|
@@ -64,4 +68,4 @@ interface DeviceAuthClient {
|
|
|
64
68
|
}
|
|
65
69
|
declare function createDeviceAuth(options: DeviceAuthOptions): DeviceAuthClient;
|
|
66
70
|
//#endregion
|
|
67
|
-
export { AuthError, type AuthErrorCode, type AuthErrorStatus, type AuthOrganization, DeviceAuthClient, DeviceAuthOptions, DeviceAuthorization, DeviceAuthorizationError, DeviceAuthorizationErrorCode, DeviceToken, DeviceTokenPersistence, type OrganizationInvitation, type OrganizationInvitationPage, type OrganizationMember, type OrganizationMemberPage, type OrganizationPage, type OrganizationPageInput, type OrganizationTeam, type OrganizationTeamMemberPage, type OrganizationTeamPage, PollDeviceOptions, type ReceivedOrganizationInvitation, type ReceivedOrganizationInvitationPage, type SocialIdTokenInput, type SocialIdTokenProvider, createDeviceAuth };
|
|
71
|
+
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 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 };
|
package/dist/device.js
CHANGED
|
@@ -614,6 +614,81 @@ function normalizeOrganization(value) {
|
|
|
614
614
|
}
|
|
615
615
|
};
|
|
616
616
|
}
|
|
617
|
+
function normalizeOrganizationDisplayInput(value) {
|
|
618
|
+
if (!isObject(value) || Object.keys(value).sort().join(",") !== "logo,name,slug") throw new AuthError("invalid_request", 400);
|
|
619
|
+
if (!boundedString(value.name, 255) || !boundedString(value.slug, 255)) throw new AuthError("invalid_request", 400);
|
|
620
|
+
let logo;
|
|
621
|
+
try {
|
|
622
|
+
logo = nullableHttpsUrl(value.logo);
|
|
623
|
+
} catch {
|
|
624
|
+
throw new AuthError("invalid_request", 400);
|
|
625
|
+
}
|
|
626
|
+
return {
|
|
627
|
+
name: value.name,
|
|
628
|
+
slug: value.slug,
|
|
629
|
+
logo
|
|
630
|
+
};
|
|
631
|
+
}
|
|
632
|
+
function normalizeOrganizationDisplay(value) {
|
|
633
|
+
try {
|
|
634
|
+
return normalizeOrganizationDisplayInput(value);
|
|
635
|
+
} catch {
|
|
636
|
+
throw authorityUnavailable();
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
function normalizeOrganizationTeamDisplayInput(value) {
|
|
640
|
+
if (!isObject(value) || Object.keys(value).join(",") !== "name" || !boundedString(value.name, 255)) throw new AuthError("invalid_request", 400);
|
|
641
|
+
return { name: value.name };
|
|
642
|
+
}
|
|
643
|
+
function normalizeOrganizationTeamDisplay(value) {
|
|
644
|
+
try {
|
|
645
|
+
return normalizeOrganizationTeamDisplayInput(value);
|
|
646
|
+
} catch {
|
|
647
|
+
throw authorityUnavailable();
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
function normalizeOrganizationTeamCreationInput(name, idempotencyKey) {
|
|
651
|
+
if (!boundedString(name, 255) || !boundedString(idempotencyKey, 255)) throw new AuthError("invalid_request", 400);
|
|
652
|
+
return {
|
|
653
|
+
name,
|
|
654
|
+
idempotencyKey
|
|
655
|
+
};
|
|
656
|
+
}
|
|
657
|
+
function normalizeCreatedOrganizationTeam(value) {
|
|
658
|
+
exact(value, ["id", "name"]);
|
|
659
|
+
if (!isId(value.id) || !boundedString(value.name, 255)) throw authorityUnavailable();
|
|
660
|
+
return {
|
|
661
|
+
id: value.id,
|
|
662
|
+
name: value.name
|
|
663
|
+
};
|
|
664
|
+
}
|
|
665
|
+
function normalizeOrganizationMemberInvitationCreationInput(value) {
|
|
666
|
+
if (!isObject(value)) throw new AuthError("invalid_request", 400);
|
|
667
|
+
const keys = Object.keys(value).sort().join(",");
|
|
668
|
+
if (keys !== "email,idempotencyKey" && keys !== "email,idempotencyKey,teamIds") throw new AuthError("invalid_request", 400);
|
|
669
|
+
let normalizedEmail;
|
|
670
|
+
try {
|
|
671
|
+
normalizedEmail = normalizeEmail(value.email);
|
|
672
|
+
} catch {
|
|
673
|
+
throw new AuthError("invalid_request", 400);
|
|
674
|
+
}
|
|
675
|
+
if (new TextEncoder().encode(normalizedEmail).byteLength > 320 || !boundedString(value.idempotencyKey, 255) || value.teamIds !== void 0 && (!Array.isArray(value.teamIds) || value.teamIds.length > 100)) throw new AuthError("invalid_request", 400);
|
|
676
|
+
const teamIds = value.teamIds?.map((teamId) => normalizeIdInput(teamId));
|
|
677
|
+
if (teamIds && new Set(teamIds).size !== teamIds.length) throw new AuthError("invalid_request", 400);
|
|
678
|
+
return {
|
|
679
|
+
email: normalizedEmail,
|
|
680
|
+
...teamIds === void 0 ? {} : { teamIds },
|
|
681
|
+
idempotencyKey: value.idempotencyKey
|
|
682
|
+
};
|
|
683
|
+
}
|
|
684
|
+
function normalizeCreatedOrganizationMemberInvitation(value) {
|
|
685
|
+
exact(value, ["expiresAt", "id"]);
|
|
686
|
+
if (!isId(value.id)) throw authorityUnavailable();
|
|
687
|
+
return {
|
|
688
|
+
id: value.id,
|
|
689
|
+
expiresAt: responseDate(value.expiresAt)
|
|
690
|
+
};
|
|
691
|
+
}
|
|
617
692
|
function normalizeOrganizations(value) {
|
|
618
693
|
exact(value, ["nextCursor", "organizations"]);
|
|
619
694
|
if (!Array.isArray(value.organizations) || value.organizations.length > 100) throw authorityUnavailable();
|
|
@@ -810,6 +885,14 @@ function fromOrganizationReadAuthorityError(value, status) {
|
|
|
810
885
|
if (status === 403) return new AuthError("access_denied", 403);
|
|
811
886
|
return authorityUnavailable();
|
|
812
887
|
}
|
|
888
|
+
function fromOrganizationMutationAuthorityError(value, status, retryAfter) {
|
|
889
|
+
if (status === 400 || status === 413 || status === 415) return new AuthError("invalid_request", 400);
|
|
890
|
+
if (status === 409) return new AuthError("state_conflict", 409);
|
|
891
|
+
if (status === 429) return new AuthError("auth_request_rate_limited", 429, parseRetryAfter(retryAfter));
|
|
892
|
+
const code = isObject(value) && typeof value.code === "string" ? value.code : void 0;
|
|
893
|
+
if (status === 403 && code === "REQUEST_ORIGIN_DENIED") return new AuthError("request_origin_denied", 403);
|
|
894
|
+
return fromOrganizationReadAuthorityError(value, status);
|
|
895
|
+
}
|
|
813
896
|
function mapError(code, status) {
|
|
814
897
|
if (code === "authentication_required") return {
|
|
815
898
|
code,
|
|
@@ -1389,6 +1472,112 @@ function createDeviceAuth(options) {
|
|
|
1389
1472
|
return Promise.reject(error);
|
|
1390
1473
|
}
|
|
1391
1474
|
},
|
|
1475
|
+
createOrganizationTeam(organizationId, name, idempotencyKey) {
|
|
1476
|
+
let id;
|
|
1477
|
+
let body;
|
|
1478
|
+
try {
|
|
1479
|
+
id = normalizeIdInput(organizationId);
|
|
1480
|
+
body = normalizeOrganizationTeamCreationInput(name, idempotencyKey);
|
|
1481
|
+
} catch (error) {
|
|
1482
|
+
return Promise.reject(error);
|
|
1483
|
+
}
|
|
1484
|
+
return serializeAuthority(async () => {
|
|
1485
|
+
const current = await readToken();
|
|
1486
|
+
if (!current) throw new AuthError("authentication_required", 401);
|
|
1487
|
+
return normalizeCreatedOrganizationTeam((await requestJsonResponse(joinURL(authOrigin, "api/v1/auth/organizations", id, "teams"), {
|
|
1488
|
+
fetch: requestFetch,
|
|
1489
|
+
timeoutMs,
|
|
1490
|
+
method: "POST",
|
|
1491
|
+
credentials: "omit",
|
|
1492
|
+
headers: {
|
|
1493
|
+
authorization: `Bearer ${current.accessToken}`,
|
|
1494
|
+
"content-type": "application/json"
|
|
1495
|
+
},
|
|
1496
|
+
body,
|
|
1497
|
+
mapError: fromOrganizationMutationAuthorityError
|
|
1498
|
+
})).value);
|
|
1499
|
+
});
|
|
1500
|
+
},
|
|
1501
|
+
createOrganizationMemberInvitation(organizationId, input) {
|
|
1502
|
+
let id;
|
|
1503
|
+
let body;
|
|
1504
|
+
try {
|
|
1505
|
+
id = normalizeIdInput(organizationId);
|
|
1506
|
+
body = normalizeOrganizationMemberInvitationCreationInput(input);
|
|
1507
|
+
} catch (error) {
|
|
1508
|
+
return Promise.reject(error);
|
|
1509
|
+
}
|
|
1510
|
+
return serializeAuthority(async () => {
|
|
1511
|
+
const current = await readToken();
|
|
1512
|
+
if (!current) throw new AuthError("authentication_required", 401);
|
|
1513
|
+
return normalizeCreatedOrganizationMemberInvitation((await requestJsonResponse(joinURL(authOrigin, "api/v1/auth/organizations", id, "invitations"), {
|
|
1514
|
+
fetch: requestFetch,
|
|
1515
|
+
timeoutMs,
|
|
1516
|
+
method: "POST",
|
|
1517
|
+
credentials: "omit",
|
|
1518
|
+
headers: {
|
|
1519
|
+
authorization: `Bearer ${current.accessToken}`,
|
|
1520
|
+
"content-type": "application/json"
|
|
1521
|
+
},
|
|
1522
|
+
body,
|
|
1523
|
+
mapError: fromOrganizationMutationAuthorityError
|
|
1524
|
+
})).value);
|
|
1525
|
+
});
|
|
1526
|
+
},
|
|
1527
|
+
updateOrganizationDisplay(organizationId, input) {
|
|
1528
|
+
let id;
|
|
1529
|
+
let desired;
|
|
1530
|
+
try {
|
|
1531
|
+
id = normalizeIdInput(organizationId);
|
|
1532
|
+
desired = normalizeOrganizationDisplayInput(input);
|
|
1533
|
+
} catch (error) {
|
|
1534
|
+
return Promise.reject(error);
|
|
1535
|
+
}
|
|
1536
|
+
return serializeAuthority(async () => {
|
|
1537
|
+
const current = await readToken();
|
|
1538
|
+
if (!current) throw new AuthError("authentication_required", 401);
|
|
1539
|
+
return normalizeOrganizationDisplay((await requestJsonResponse(joinURL(authOrigin, "api/v1/auth/organizations", id, "display"), {
|
|
1540
|
+
fetch: requestFetch,
|
|
1541
|
+
timeoutMs,
|
|
1542
|
+
method: "POST",
|
|
1543
|
+
credentials: "omit",
|
|
1544
|
+
headers: {
|
|
1545
|
+
authorization: `Bearer ${current.accessToken}`,
|
|
1546
|
+
"content-type": "application/json"
|
|
1547
|
+
},
|
|
1548
|
+
body: desired,
|
|
1549
|
+
mapError: fromOrganizationMutationAuthorityError
|
|
1550
|
+
})).value);
|
|
1551
|
+
});
|
|
1552
|
+
},
|
|
1553
|
+
updateOrganizationTeamDisplay(organizationId, teamId, input) {
|
|
1554
|
+
let organization;
|
|
1555
|
+
let team;
|
|
1556
|
+
let desired;
|
|
1557
|
+
try {
|
|
1558
|
+
organization = normalizeIdInput(organizationId);
|
|
1559
|
+
team = normalizeIdInput(teamId);
|
|
1560
|
+
desired = normalizeOrganizationTeamDisplayInput(input);
|
|
1561
|
+
} catch (error) {
|
|
1562
|
+
return Promise.reject(error);
|
|
1563
|
+
}
|
|
1564
|
+
return serializeAuthority(async () => {
|
|
1565
|
+
const current = await readToken();
|
|
1566
|
+
if (!current) throw new AuthError("authentication_required", 401);
|
|
1567
|
+
return normalizeOrganizationTeamDisplay((await requestJsonResponse(joinURL(authOrigin, "api/v1/auth/organizations", organization, "teams", team, "display"), {
|
|
1568
|
+
fetch: requestFetch,
|
|
1569
|
+
timeoutMs,
|
|
1570
|
+
method: "POST",
|
|
1571
|
+
credentials: "omit",
|
|
1572
|
+
headers: {
|
|
1573
|
+
authorization: `Bearer ${current.accessToken}`,
|
|
1574
|
+
"content-type": "application/json"
|
|
1575
|
+
},
|
|
1576
|
+
body: desired,
|
|
1577
|
+
mapError: fromOrganizationMutationAuthorityError
|
|
1578
|
+
})).value);
|
|
1579
|
+
});
|
|
1580
|
+
},
|
|
1392
1581
|
listOrganizationMembers(organizationId, input) {
|
|
1393
1582
|
try {
|
|
1394
1583
|
return serializeAuthority(() => organizationRead(`${normalizeIdInput(organizationId)}/members`, input, normalizeOrganizationMembers));
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { A as
|
|
1
|
+
import { A as ReceivedOrganizationInvitationPage, B as AuthErrorCode, C as OrganizationTeam, D as OrganizationWorkspaceSelection, E as OrganizationTeamPage, F as UpdateOrganizationDisplayInput, I as UpdateOrganizationTeamDisplayInput, L as UpdateProfileInput, M as SignInInput, N as SocialIdTokenInput, O as PersonalWorkspaceSelection, P as SocialIdTokenProvider, R as WorkspaceSelection, S as OrganizationPageInput, T as OrganizationTeamMemberPage, V 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 SendVerificationEmailInput, k as ReceivedOrganizationInvitation, l as CreateOrganizationMemberInvitationInput, m as FinuevaAuthClient, n as AuthClientOptions, o as AuthSession, p as DriveCredentialInput, 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 AuthError } from "./types-Byw9JQwL.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 DriveCredential, type DriveCredentialInput, type FinuevaAuthClient, type InvitationAcceptance, type OrganizationInvitation, type OrganizationInvitationPage, type OrganizationMember, type OrganizationMemberPage, type OrganizationPage, type OrganizationPageInput, type OrganizationTeam, type OrganizationTeamMemberPage, type OrganizationTeamPage, type OrganizationWorkspaceSelection, type PersonalWorkspaceSelection, type ReceivedOrganizationInvitation, type ReceivedOrganizationInvitationPage, type SendVerificationEmailInput, type SignInInput, type SocialIdTokenInput, type SocialIdTokenProvider, 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 ReceivedOrganizationInvitation, type ReceivedOrganizationInvitationPage, type SendVerificationEmailInput, type SignInInput, type SocialIdTokenInput, type SocialIdTokenProvider, type UpdateOrganizationDisplayInput, type UpdateOrganizationTeamDisplayInput, type UpdateProfileInput, type WorkspaceSelection, createAuthClient };
|
package/dist/index.js
CHANGED
|
@@ -2333,6 +2333,81 @@ function normalizeOrganization(value) {
|
|
|
2333
2333
|
}
|
|
2334
2334
|
};
|
|
2335
2335
|
}
|
|
2336
|
+
function normalizeOrganizationDisplayInput(value) {
|
|
2337
|
+
if (!isObject(value) || Object.keys(value).sort().join(",") !== "logo,name,slug") throw new AuthError("invalid_request", 400);
|
|
2338
|
+
if (!boundedString(value.name, 255) || !boundedString(value.slug, 255)) throw new AuthError("invalid_request", 400);
|
|
2339
|
+
let logo;
|
|
2340
|
+
try {
|
|
2341
|
+
logo = nullableHttpsUrl(value.logo);
|
|
2342
|
+
} catch {
|
|
2343
|
+
throw new AuthError("invalid_request", 400);
|
|
2344
|
+
}
|
|
2345
|
+
return {
|
|
2346
|
+
name: value.name,
|
|
2347
|
+
slug: value.slug,
|
|
2348
|
+
logo
|
|
2349
|
+
};
|
|
2350
|
+
}
|
|
2351
|
+
function normalizeOrganizationDisplay(value) {
|
|
2352
|
+
try {
|
|
2353
|
+
return normalizeOrganizationDisplayInput(value);
|
|
2354
|
+
} catch {
|
|
2355
|
+
throw authorityUnavailable();
|
|
2356
|
+
}
|
|
2357
|
+
}
|
|
2358
|
+
function normalizeOrganizationTeamDisplayInput(value) {
|
|
2359
|
+
if (!isObject(value) || Object.keys(value).join(",") !== "name" || !boundedString(value.name, 255)) throw new AuthError("invalid_request", 400);
|
|
2360
|
+
return { name: value.name };
|
|
2361
|
+
}
|
|
2362
|
+
function normalizeOrganizationTeamDisplay(value) {
|
|
2363
|
+
try {
|
|
2364
|
+
return normalizeOrganizationTeamDisplayInput(value);
|
|
2365
|
+
} catch {
|
|
2366
|
+
throw authorityUnavailable();
|
|
2367
|
+
}
|
|
2368
|
+
}
|
|
2369
|
+
function normalizeOrganizationTeamCreationInput(name, idempotencyKey) {
|
|
2370
|
+
if (!boundedString(name, 255) || !boundedString(idempotencyKey, 255)) throw new AuthError("invalid_request", 400);
|
|
2371
|
+
return {
|
|
2372
|
+
name,
|
|
2373
|
+
idempotencyKey
|
|
2374
|
+
};
|
|
2375
|
+
}
|
|
2376
|
+
function normalizeCreatedOrganizationTeam(value) {
|
|
2377
|
+
exact(value, ["id", "name"]);
|
|
2378
|
+
if (!isId(value.id) || !boundedString(value.name, 255)) throw authorityUnavailable();
|
|
2379
|
+
return {
|
|
2380
|
+
id: value.id,
|
|
2381
|
+
name: value.name
|
|
2382
|
+
};
|
|
2383
|
+
}
|
|
2384
|
+
function normalizeOrganizationMemberInvitationCreationInput(value) {
|
|
2385
|
+
if (!isObject(value)) throw new AuthError("invalid_request", 400);
|
|
2386
|
+
const keys = Object.keys(value).sort().join(",");
|
|
2387
|
+
if (keys !== "email,idempotencyKey" && keys !== "email,idempotencyKey,teamIds") throw new AuthError("invalid_request", 400);
|
|
2388
|
+
let normalizedEmail;
|
|
2389
|
+
try {
|
|
2390
|
+
normalizedEmail = normalizeEmail(value.email);
|
|
2391
|
+
} catch {
|
|
2392
|
+
throw new AuthError("invalid_request", 400);
|
|
2393
|
+
}
|
|
2394
|
+
if (new TextEncoder().encode(normalizedEmail).byteLength > 320 || !boundedString(value.idempotencyKey, 255) || value.teamIds !== void 0 && (!Array.isArray(value.teamIds) || value.teamIds.length > 100)) throw new AuthError("invalid_request", 400);
|
|
2395
|
+
const teamIds = value.teamIds?.map((teamId) => normalizeIdInput(teamId));
|
|
2396
|
+
if (teamIds && new Set(teamIds).size !== teamIds.length) throw new AuthError("invalid_request", 400);
|
|
2397
|
+
return {
|
|
2398
|
+
email: normalizedEmail,
|
|
2399
|
+
...teamIds === void 0 ? {} : { teamIds },
|
|
2400
|
+
idempotencyKey: value.idempotencyKey
|
|
2401
|
+
};
|
|
2402
|
+
}
|
|
2403
|
+
function normalizeCreatedOrganizationMemberInvitation(value) {
|
|
2404
|
+
exact(value, ["expiresAt", "id"]);
|
|
2405
|
+
if (!isId(value.id)) throw authorityUnavailable();
|
|
2406
|
+
return {
|
|
2407
|
+
id: value.id,
|
|
2408
|
+
expiresAt: responseDate(value.expiresAt)
|
|
2409
|
+
};
|
|
2410
|
+
}
|
|
2336
2411
|
function normalizeOrganizations(value) {
|
|
2337
2412
|
exact(value, ["nextCursor", "organizations"]);
|
|
2338
2413
|
if (!Array.isArray(value.organizations) || value.organizations.length > 100) throw authorityUnavailable();
|
|
@@ -2556,6 +2631,14 @@ function fromOrganizationReadAuthorityError(value, status) {
|
|
|
2556
2631
|
if (status === 403) return new AuthError("access_denied", 403);
|
|
2557
2632
|
return authorityUnavailable();
|
|
2558
2633
|
}
|
|
2634
|
+
function fromOrganizationMutationAuthorityError(value, status, retryAfter) {
|
|
2635
|
+
if (status === 400 || status === 413 || status === 415) return new AuthError("invalid_request", 400);
|
|
2636
|
+
if (status === 409) return new AuthError("state_conflict", 409);
|
|
2637
|
+
if (status === 429) return new AuthError("auth_request_rate_limited", 429, parseRetryAfter(retryAfter));
|
|
2638
|
+
const code = isObject(value) && typeof value.code === "string" ? value.code : void 0;
|
|
2639
|
+
if (status === 403 && code === "REQUEST_ORIGIN_DENIED") return new AuthError("request_origin_denied", 403);
|
|
2640
|
+
return fromOrganizationReadAuthorityError(value, status);
|
|
2641
|
+
}
|
|
2559
2642
|
function fromInvitationAuthorityError(value, status) {
|
|
2560
2643
|
const code = isObject(value) && typeof value.code === "string" ? value.code : void 0;
|
|
2561
2644
|
if (status === 401 && code === "UNAUTHORIZED") return new AuthError("authentication_required", 401);
|
|
@@ -3841,6 +3924,71 @@ function createAuthClient(options) {
|
|
|
3841
3924
|
async getOrganization(organizationId) {
|
|
3842
3925
|
return organizationRead(normalizeIdInput(organizationId), void 0, normalizeOrganization);
|
|
3843
3926
|
},
|
|
3927
|
+
async createOrganizationTeam(organizationId, name, idempotencyKey) {
|
|
3928
|
+
const id = normalizeIdInput(organizationId);
|
|
3929
|
+
const body = normalizeOrganizationTeamCreationInput(name, idempotencyKey);
|
|
3930
|
+
if (signOutRequest || activeAccountMutationGeneration !== void 0 || invitationRequest) throw new AuthError("state_conflict", 409);
|
|
3931
|
+
const generation = authorityGeneration;
|
|
3932
|
+
const value = await requestJson(joinURL(authOrigin, "api/v1/auth/organizations", id, "teams"), {
|
|
3933
|
+
fetch: fetchImpl,
|
|
3934
|
+
timeoutMs,
|
|
3935
|
+
method: "POST",
|
|
3936
|
+
headers: { "content-type": "application/json" },
|
|
3937
|
+
body,
|
|
3938
|
+
mapError: fromOrganizationMutationAuthorityError
|
|
3939
|
+
});
|
|
3940
|
+
if (generation !== authorityGeneration) throw new AuthError("state_conflict", 409);
|
|
3941
|
+
return normalizeCreatedOrganizationTeam(value);
|
|
3942
|
+
},
|
|
3943
|
+
async createOrganizationMemberInvitation(organizationId, input) {
|
|
3944
|
+
const id = normalizeIdInput(organizationId);
|
|
3945
|
+
const body = normalizeOrganizationMemberInvitationCreationInput(input);
|
|
3946
|
+
if (signOutRequest || activeAccountMutationGeneration !== void 0 || invitationRequest) throw new AuthError("state_conflict", 409);
|
|
3947
|
+
const generation = authorityGeneration;
|
|
3948
|
+
const value = await requestJson(joinURL(authOrigin, "api/v1/auth/organizations", id, "invitations"), {
|
|
3949
|
+
fetch: fetchImpl,
|
|
3950
|
+
timeoutMs,
|
|
3951
|
+
method: "POST",
|
|
3952
|
+
headers: { "content-type": "application/json" },
|
|
3953
|
+
body,
|
|
3954
|
+
mapError: fromOrganizationMutationAuthorityError
|
|
3955
|
+
});
|
|
3956
|
+
if (generation !== authorityGeneration) throw new AuthError("state_conflict", 409);
|
|
3957
|
+
return normalizeCreatedOrganizationMemberInvitation(value);
|
|
3958
|
+
},
|
|
3959
|
+
async updateOrganizationDisplay(organizationId, input) {
|
|
3960
|
+
const id = normalizeIdInput(organizationId);
|
|
3961
|
+
const desired = normalizeOrganizationDisplayInput(input);
|
|
3962
|
+
if (signOutRequest || activeAccountMutationGeneration !== void 0 || invitationRequest) throw new AuthError("state_conflict", 409);
|
|
3963
|
+
const generation = authorityGeneration;
|
|
3964
|
+
const value = await requestJson(joinURL(authOrigin, "api/v1/auth/organizations", id, "display"), {
|
|
3965
|
+
fetch: fetchImpl,
|
|
3966
|
+
timeoutMs,
|
|
3967
|
+
method: "POST",
|
|
3968
|
+
headers: { "content-type": "application/json" },
|
|
3969
|
+
body: desired,
|
|
3970
|
+
mapError: fromOrganizationMutationAuthorityError
|
|
3971
|
+
});
|
|
3972
|
+
if (generation !== authorityGeneration) throw new AuthError("state_conflict", 409);
|
|
3973
|
+
return normalizeOrganizationDisplay(value);
|
|
3974
|
+
},
|
|
3975
|
+
async updateOrganizationTeamDisplay(organizationId, teamId, input) {
|
|
3976
|
+
const organization = normalizeIdInput(organizationId);
|
|
3977
|
+
const team = normalizeIdInput(teamId);
|
|
3978
|
+
const desired = normalizeOrganizationTeamDisplayInput(input);
|
|
3979
|
+
if (signOutRequest || activeAccountMutationGeneration !== void 0 || invitationRequest) throw new AuthError("state_conflict", 409);
|
|
3980
|
+
const generation = authorityGeneration;
|
|
3981
|
+
const value = await requestJson(joinURL(authOrigin, "api/v1/auth/organizations", organization, "teams", team, "display"), {
|
|
3982
|
+
fetch: fetchImpl,
|
|
3983
|
+
timeoutMs,
|
|
3984
|
+
method: "POST",
|
|
3985
|
+
headers: { "content-type": "application/json" },
|
|
3986
|
+
body: desired,
|
|
3987
|
+
mapError: fromOrganizationMutationAuthorityError
|
|
3988
|
+
});
|
|
3989
|
+
if (generation !== authorityGeneration) throw new AuthError("state_conflict", 409);
|
|
3990
|
+
return normalizeOrganizationTeamDisplay(value);
|
|
3991
|
+
},
|
|
3844
3992
|
async listOrganizationMembers(organizationId, input) {
|
|
3845
3993
|
return organizationRead(`${normalizeIdInput(organizationId)}/members`, input, normalizeOrganizationMembers);
|
|
3846
3994
|
},
|
package/dist/server.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { C as
|
|
1
|
+
import { A as ReceivedOrganizationInvitationPage, B as AuthErrorCode, C as OrganizationTeam, D as OrganizationWorkspaceSelection, E as OrganizationTeamPage, F as UpdateOrganizationDisplayInput, I as UpdateOrganizationTeamDisplayInput, N as SocialIdTokenInput, O as PersonalWorkspaceSelection, P as SocialIdTokenProvider, R as WorkspaceSelection, S as OrganizationPageInput, T as OrganizationTeamMemberPage, V as AuthErrorStatus, _ as OrganizationInvitation, b as OrganizationMemberPage, c as AuthUser, d as CreatedOrganizationTeam, f as DriveCredential, g as OrganizationDisplay, h as InvitationAcceptance, k as ReceivedOrganizationInvitation, l as CreateOrganizationMemberInvitationInput, o as AuthSession, p as DriveCredentialInput, r as AuthOrganization, t as AcceptInvitationInput, u as CreatedOrganizationMemberInvitation, v as OrganizationInvitationPage, w as OrganizationTeamDisplay, x as OrganizationPage, y as OrganizationMember, z as AuthError } from "./types-Byw9JQwL.js";
|
|
2
2
|
//#region src/server.d.ts
|
|
3
3
|
interface ServerAuthOptions {
|
|
4
4
|
authOrigin: string;
|
|
@@ -22,6 +22,10 @@ interface FinuevaServerAuth {
|
|
|
22
22
|
getSession(): Promise<AuthSession | null>;
|
|
23
23
|
listOrganizations(input?: OrganizationPageInput): Promise<OrganizationPage>;
|
|
24
24
|
getOrganization(organizationId: string): Promise<AuthOrganization>;
|
|
25
|
+
createOrganizationTeam(organizationId: string, name: string, idempotencyKey: string): Promise<CreatedOrganizationTeam>;
|
|
26
|
+
createOrganizationMemberInvitation(organizationId: string, input: CreateOrganizationMemberInvitationInput): Promise<CreatedOrganizationMemberInvitation>;
|
|
27
|
+
updateOrganizationDisplay(organizationId: string, input: UpdateOrganizationDisplayInput): Promise<OrganizationDisplay>;
|
|
28
|
+
updateOrganizationTeamDisplay(organizationId: string, teamId: string, input: UpdateOrganizationTeamDisplayInput): Promise<OrganizationTeamDisplay>;
|
|
25
29
|
listOrganizationMembers(organizationId: string, input?: OrganizationPageInput): Promise<OrganizationMemberPage>;
|
|
26
30
|
listOrganizationTeams(organizationId: string, input?: OrganizationPageInput): Promise<OrganizationTeamPage>;
|
|
27
31
|
listOrganizationTeamMembers(organizationId: string, teamId: string, input?: OrganizationPageInput): Promise<OrganizationTeamMemberPage>;
|
|
@@ -35,4 +39,4 @@ interface FinuevaServerAuth {
|
|
|
35
39
|
}
|
|
36
40
|
declare function createServerAuth(options: ServerAuthOptions): FinuevaServerAuth;
|
|
37
41
|
//#endregion
|
|
38
|
-
export { type AcceptInvitationInput, AuthError, type AuthErrorCode, type AuthErrorStatus, type AuthOrganization, type AuthSession, type AuthUser, type DriveCredential, type DriveCredentialInput, FinuevaServerAuth, type InvitationAcceptance, type OrganizationInvitation, type OrganizationInvitationPage, type OrganizationMember, type OrganizationMemberPage, type OrganizationPage, type OrganizationPageInput, type OrganizationTeam, type OrganizationTeamMemberPage, type OrganizationTeamPage, type OrganizationWorkspaceSelection, type PersonalWorkspaceSelection, type ReceivedOrganizationInvitation, type ReceivedOrganizationInvitationPage, ServerAuthOptions, ServerInvitationAcceptance, ServerSignOutResult, ServerSocialIdTokenSession, type SocialIdTokenInput, type SocialIdTokenProvider, type WorkspaceSelection, createServerAuth };
|
|
42
|
+
export { type AcceptInvitationInput, AuthError, type AuthErrorCode, type AuthErrorStatus, type AuthOrganization, type AuthSession, type AuthUser, type CreateOrganizationMemberInvitationInput, type CreatedOrganizationMemberInvitation, type CreatedOrganizationTeam, type DriveCredential, type DriveCredentialInput, FinuevaServerAuth, 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 ReceivedOrganizationInvitation, type ReceivedOrganizationInvitationPage, ServerAuthOptions, ServerInvitationAcceptance, ServerSignOutResult, ServerSocialIdTokenSession, type SocialIdTokenInput, type SocialIdTokenProvider, type UpdateOrganizationDisplayInput, type UpdateOrganizationTeamDisplayInput, type WorkspaceSelection, createServerAuth };
|
package/dist/server.js
CHANGED
|
@@ -475,6 +475,12 @@ const DRIVE_CREDENTIAL_LIFETIME_SECONDS = 840;
|
|
|
475
475
|
const id = /^[A-Za-z0-9_-]{1,128}$/;
|
|
476
476
|
const email = /^[^\s@]+@[^\s@]+$/;
|
|
477
477
|
const MAX_SOCIAL_ID_TOKEN_BYTES = 16 * 1024;
|
|
478
|
+
function normalizeEmail(value) {
|
|
479
|
+
if (typeof value !== "string") throw new TypeError("email is invalid");
|
|
480
|
+
const normalized = value.trim().toLowerCase();
|
|
481
|
+
if (normalized.length === 0 || normalized.length > 320 || !email.test(normalized)) throw new TypeError("email is invalid");
|
|
482
|
+
return normalized;
|
|
483
|
+
}
|
|
478
484
|
function normalizeSocialIdTokenInput(value) {
|
|
479
485
|
if (!isObject(value)) throw new TypeError("social ID token input is invalid");
|
|
480
486
|
const keys = Object.keys(value);
|
|
@@ -589,6 +595,81 @@ function normalizeOrganization(value) {
|
|
|
589
595
|
}
|
|
590
596
|
};
|
|
591
597
|
}
|
|
598
|
+
function normalizeOrganizationDisplayInput(value) {
|
|
599
|
+
if (!isObject(value) || Object.keys(value).sort().join(",") !== "logo,name,slug") throw new AuthError("invalid_request", 400);
|
|
600
|
+
if (!boundedString(value.name, 255) || !boundedString(value.slug, 255)) throw new AuthError("invalid_request", 400);
|
|
601
|
+
let logo;
|
|
602
|
+
try {
|
|
603
|
+
logo = nullableHttpsUrl(value.logo);
|
|
604
|
+
} catch {
|
|
605
|
+
throw new AuthError("invalid_request", 400);
|
|
606
|
+
}
|
|
607
|
+
return {
|
|
608
|
+
name: value.name,
|
|
609
|
+
slug: value.slug,
|
|
610
|
+
logo
|
|
611
|
+
};
|
|
612
|
+
}
|
|
613
|
+
function normalizeOrganizationDisplay(value) {
|
|
614
|
+
try {
|
|
615
|
+
return normalizeOrganizationDisplayInput(value);
|
|
616
|
+
} catch {
|
|
617
|
+
throw authorityUnavailable();
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
function normalizeOrganizationTeamDisplayInput(value) {
|
|
621
|
+
if (!isObject(value) || Object.keys(value).join(",") !== "name" || !boundedString(value.name, 255)) throw new AuthError("invalid_request", 400);
|
|
622
|
+
return { name: value.name };
|
|
623
|
+
}
|
|
624
|
+
function normalizeOrganizationTeamDisplay(value) {
|
|
625
|
+
try {
|
|
626
|
+
return normalizeOrganizationTeamDisplayInput(value);
|
|
627
|
+
} catch {
|
|
628
|
+
throw authorityUnavailable();
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
function normalizeOrganizationTeamCreationInput(name, idempotencyKey) {
|
|
632
|
+
if (!boundedString(name, 255) || !boundedString(idempotencyKey, 255)) throw new AuthError("invalid_request", 400);
|
|
633
|
+
return {
|
|
634
|
+
name,
|
|
635
|
+
idempotencyKey
|
|
636
|
+
};
|
|
637
|
+
}
|
|
638
|
+
function normalizeCreatedOrganizationTeam(value) {
|
|
639
|
+
exact(value, ["id", "name"]);
|
|
640
|
+
if (!isId(value.id) || !boundedString(value.name, 255)) throw authorityUnavailable();
|
|
641
|
+
return {
|
|
642
|
+
id: value.id,
|
|
643
|
+
name: value.name
|
|
644
|
+
};
|
|
645
|
+
}
|
|
646
|
+
function normalizeOrganizationMemberInvitationCreationInput(value) {
|
|
647
|
+
if (!isObject(value)) throw new AuthError("invalid_request", 400);
|
|
648
|
+
const keys = Object.keys(value).sort().join(",");
|
|
649
|
+
if (keys !== "email,idempotencyKey" && keys !== "email,idempotencyKey,teamIds") throw new AuthError("invalid_request", 400);
|
|
650
|
+
let normalizedEmail;
|
|
651
|
+
try {
|
|
652
|
+
normalizedEmail = normalizeEmail(value.email);
|
|
653
|
+
} catch {
|
|
654
|
+
throw new AuthError("invalid_request", 400);
|
|
655
|
+
}
|
|
656
|
+
if (new TextEncoder().encode(normalizedEmail).byteLength > 320 || !boundedString(value.idempotencyKey, 255) || value.teamIds !== void 0 && (!Array.isArray(value.teamIds) || value.teamIds.length > 100)) throw new AuthError("invalid_request", 400);
|
|
657
|
+
const teamIds = value.teamIds?.map((teamId) => normalizeIdInput(teamId));
|
|
658
|
+
if (teamIds && new Set(teamIds).size !== teamIds.length) throw new AuthError("invalid_request", 400);
|
|
659
|
+
return {
|
|
660
|
+
email: normalizedEmail,
|
|
661
|
+
...teamIds === void 0 ? {} : { teamIds },
|
|
662
|
+
idempotencyKey: value.idempotencyKey
|
|
663
|
+
};
|
|
664
|
+
}
|
|
665
|
+
function normalizeCreatedOrganizationMemberInvitation(value) {
|
|
666
|
+
exact(value, ["expiresAt", "id"]);
|
|
667
|
+
if (!isId(value.id)) throw authorityUnavailable();
|
|
668
|
+
return {
|
|
669
|
+
id: value.id,
|
|
670
|
+
expiresAt: responseDate(value.expiresAt)
|
|
671
|
+
};
|
|
672
|
+
}
|
|
592
673
|
function normalizeOrganizations(value) {
|
|
593
674
|
exact(value, ["nextCursor", "organizations"]);
|
|
594
675
|
if (!Array.isArray(value.organizations) || value.organizations.length > 100) throw authorityUnavailable();
|
|
@@ -798,6 +879,14 @@ function fromOrganizationReadAuthorityError(value, status) {
|
|
|
798
879
|
if (status === 403) return new AuthError("access_denied", 403);
|
|
799
880
|
return authorityUnavailable();
|
|
800
881
|
}
|
|
882
|
+
function fromOrganizationMutationAuthorityError(value, status, retryAfter) {
|
|
883
|
+
if (status === 400 || status === 413 || status === 415) return new AuthError("invalid_request", 400);
|
|
884
|
+
if (status === 409) return new AuthError("state_conflict", 409);
|
|
885
|
+
if (status === 429) return new AuthError("auth_request_rate_limited", 429, parseRetryAfter(retryAfter));
|
|
886
|
+
const code = isObject(value) && typeof value.code === "string" ? value.code : void 0;
|
|
887
|
+
if (status === 403 && code === "REQUEST_ORIGIN_DENIED") return new AuthError("request_origin_denied", 403);
|
|
888
|
+
return fromOrganizationReadAuthorityError(value, status);
|
|
889
|
+
}
|
|
801
890
|
function fromInvitationAuthorityError(value, status) {
|
|
802
891
|
const code = isObject(value) && typeof value.code === "string" ? value.code : void 0;
|
|
803
892
|
if (status === 401 && code === "UNAUTHORIZED") return new AuthError("authentication_required", 401);
|
|
@@ -1062,6 +1151,71 @@ function createServerAuth(options) {
|
|
|
1062
1151
|
getOrganization(organizationId) {
|
|
1063
1152
|
return organizationRead(normalizeIdInput(organizationId), void 0, normalizeOrganization);
|
|
1064
1153
|
},
|
|
1154
|
+
async createOrganizationTeam(organizationId, name, idempotencyKey) {
|
|
1155
|
+
const id = normalizeIdInput(organizationId);
|
|
1156
|
+
const body = normalizeOrganizationTeamCreationInput(name, idempotencyKey);
|
|
1157
|
+
return normalizeCreatedOrganizationTeam(await requestJson(joinURL(authOrigin, "api/v1/auth/organizations", id, "teams"), {
|
|
1158
|
+
fetch: fetchImpl,
|
|
1159
|
+
timeoutMs,
|
|
1160
|
+
method: "POST",
|
|
1161
|
+
credentials,
|
|
1162
|
+
headers: {
|
|
1163
|
+
...authHeaders(!authorization),
|
|
1164
|
+
"content-type": "application/json"
|
|
1165
|
+
},
|
|
1166
|
+
body,
|
|
1167
|
+
mapError: fromOrganizationMutationAuthorityError
|
|
1168
|
+
}));
|
|
1169
|
+
},
|
|
1170
|
+
async createOrganizationMemberInvitation(organizationId, input) {
|
|
1171
|
+
const id = normalizeIdInput(organizationId);
|
|
1172
|
+
const body = normalizeOrganizationMemberInvitationCreationInput(input);
|
|
1173
|
+
return normalizeCreatedOrganizationMemberInvitation(await requestJson(joinURL(authOrigin, "api/v1/auth/organizations", id, "invitations"), {
|
|
1174
|
+
fetch: fetchImpl,
|
|
1175
|
+
timeoutMs,
|
|
1176
|
+
method: "POST",
|
|
1177
|
+
credentials,
|
|
1178
|
+
headers: {
|
|
1179
|
+
...authHeaders(!authorization),
|
|
1180
|
+
"content-type": "application/json"
|
|
1181
|
+
},
|
|
1182
|
+
body,
|
|
1183
|
+
mapError: fromOrganizationMutationAuthorityError
|
|
1184
|
+
}));
|
|
1185
|
+
},
|
|
1186
|
+
async updateOrganizationDisplay(organizationId, input) {
|
|
1187
|
+
const id = normalizeIdInput(organizationId);
|
|
1188
|
+
const desired = normalizeOrganizationDisplayInput(input);
|
|
1189
|
+
return normalizeOrganizationDisplay(await requestJson(joinURL(authOrigin, "api/v1/auth/organizations", id, "display"), {
|
|
1190
|
+
fetch: fetchImpl,
|
|
1191
|
+
timeoutMs,
|
|
1192
|
+
method: "POST",
|
|
1193
|
+
credentials,
|
|
1194
|
+
headers: {
|
|
1195
|
+
...authHeaders(!authorization),
|
|
1196
|
+
"content-type": "application/json"
|
|
1197
|
+
},
|
|
1198
|
+
body: desired,
|
|
1199
|
+
mapError: fromOrganizationMutationAuthorityError
|
|
1200
|
+
}));
|
|
1201
|
+
},
|
|
1202
|
+
async updateOrganizationTeamDisplay(organizationId, teamId, input) {
|
|
1203
|
+
const organization = normalizeIdInput(organizationId);
|
|
1204
|
+
const team = normalizeIdInput(teamId);
|
|
1205
|
+
const desired = normalizeOrganizationTeamDisplayInput(input);
|
|
1206
|
+
return normalizeOrganizationTeamDisplay(await requestJson(joinURL(authOrigin, "api/v1/auth/organizations", organization, "teams", team, "display"), {
|
|
1207
|
+
fetch: fetchImpl,
|
|
1208
|
+
timeoutMs,
|
|
1209
|
+
method: "POST",
|
|
1210
|
+
credentials,
|
|
1211
|
+
headers: {
|
|
1212
|
+
...authHeaders(!authorization),
|
|
1213
|
+
"content-type": "application/json"
|
|
1214
|
+
},
|
|
1215
|
+
body: desired,
|
|
1216
|
+
mapError: fromOrganizationMutationAuthorityError
|
|
1217
|
+
}));
|
|
1218
|
+
},
|
|
1065
1219
|
listOrganizationMembers(organizationId, input) {
|
|
1066
1220
|
return organizationRead(`${normalizeIdInput(organizationId)}/members`, input, normalizeOrganizationMembers);
|
|
1067
1221
|
},
|
|
@@ -34,6 +34,16 @@ interface AuthOrganization {
|
|
|
34
34
|
readInvitations: boolean;
|
|
35
35
|
};
|
|
36
36
|
}
|
|
37
|
+
interface OrganizationDisplay {
|
|
38
|
+
name: string;
|
|
39
|
+
slug: string;
|
|
40
|
+
logo: string | null;
|
|
41
|
+
}
|
|
42
|
+
type UpdateOrganizationDisplayInput = OrganizationDisplay;
|
|
43
|
+
interface OrganizationTeamDisplay {
|
|
44
|
+
name: string;
|
|
45
|
+
}
|
|
46
|
+
type UpdateOrganizationTeamDisplayInput = OrganizationTeamDisplay;
|
|
37
47
|
interface OrganizationPageInput {
|
|
38
48
|
limit?: number;
|
|
39
49
|
cursor?: string;
|
|
@@ -63,6 +73,19 @@ interface OrganizationTeam {
|
|
|
63
73
|
category: "manual" | "managed";
|
|
64
74
|
createdAt: Date;
|
|
65
75
|
}
|
|
76
|
+
interface CreatedOrganizationTeam {
|
|
77
|
+
id: string;
|
|
78
|
+
name: string;
|
|
79
|
+
}
|
|
80
|
+
interface CreateOrganizationMemberInvitationInput {
|
|
81
|
+
email: string;
|
|
82
|
+
teamIds?: string[];
|
|
83
|
+
idempotencyKey: string;
|
|
84
|
+
}
|
|
85
|
+
interface CreatedOrganizationMemberInvitation {
|
|
86
|
+
id: string;
|
|
87
|
+
expiresAt: Date;
|
|
88
|
+
}
|
|
66
89
|
interface OrganizationTeamPage {
|
|
67
90
|
teams: OrganizationTeam[];
|
|
68
91
|
nextCursor: string | null;
|
|
@@ -184,6 +207,10 @@ interface FinuevaAuthClient {
|
|
|
184
207
|
getSession(): Promise<AuthSession | null>;
|
|
185
208
|
listOrganizations(input?: OrganizationPageInput): Promise<OrganizationPage>;
|
|
186
209
|
getOrganization(organizationId: string): Promise<AuthOrganization>;
|
|
210
|
+
createOrganizationTeam(organizationId: string, name: string, idempotencyKey: string): Promise<CreatedOrganizationTeam>;
|
|
211
|
+
createOrganizationMemberInvitation(organizationId: string, input: CreateOrganizationMemberInvitationInput): Promise<CreatedOrganizationMemberInvitation>;
|
|
212
|
+
updateOrganizationDisplay(organizationId: string, input: UpdateOrganizationDisplayInput): Promise<OrganizationDisplay>;
|
|
213
|
+
updateOrganizationTeamDisplay(organizationId: string, teamId: string, input: UpdateOrganizationTeamDisplayInput): Promise<OrganizationTeamDisplay>;
|
|
187
214
|
listOrganizationMembers(organizationId: string, input?: OrganizationPageInput): Promise<OrganizationMemberPage>;
|
|
188
215
|
listOrganizationTeams(organizationId: string, input?: OrganizationPageInput): Promise<OrganizationTeamPage>;
|
|
189
216
|
listOrganizationTeamMembers(organizationId: string, teamId: string, input?: OrganizationPageInput): Promise<OrganizationTeamMemberPage>;
|
|
@@ -205,4 +232,4 @@ interface FinuevaAuthClient {
|
|
|
205
232
|
onSessionChange(listener: (session: AuthSession | null) => void): () => void;
|
|
206
233
|
}
|
|
207
234
|
//#endregion
|
|
208
|
-
export {
|
|
235
|
+
export { ReceivedOrganizationInvitationPage as A, AuthErrorCode as B, OrganizationTeam as C, OrganizationWorkspaceSelection as D, OrganizationTeamPage as E, UpdateOrganizationDisplayInput as F, UpdateOrganizationTeamDisplayInput as I, UpdateProfileInput as L, SignInInput as M, SocialIdTokenInput as N, PersonalWorkspaceSelection as O, SocialIdTokenProvider as P, WorkspaceSelection as R, OrganizationPageInput as S, OrganizationTeamMemberPage as T, AuthErrorStatus as V, 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, SendVerificationEmailInput as j, ReceivedOrganizationInvitation as k, CreateOrganizationMemberInvitationInput as l, FinuevaAuthClient as m, AuthClientOptions as n, AuthSession as o, DriveCredentialInput as p, AuthOrganization as r, AuthState as s, AcceptInvitationInput as t, CreatedOrganizationMemberInvitation as u, OrganizationInvitationPage as v, OrganizationTeamDisplay as w, OrganizationPage as x, OrganizationMember as y, AuthError as z };
|