@finueva/auth 0.1.0 → 0.4.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 +55 -5
- package/THIRD_PARTY_NOTICES.md +52 -0
- package/dist/device.d.ts +51 -0
- package/dist/device.js +936 -0
- package/dist/errors-Crd93Rah.d.ts +11 -0
- package/dist/index.d.ts +3 -2
- package/dist/index.js +999 -46
- package/dist/server.d.ts +8 -2
- package/dist/server.js +139 -30
- package/dist/types-zEqO1_r2.d.ts +90 -0
- package/package.json +10 -2
- package/dist/errors-C-cHFWC7.d.ts +0 -55
package/dist/server.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { c as AuthUser, f as InvitationAcceptance, g as WorkspaceSelection, l as DriveCredential, m as PersonalWorkspaceSelection, o as AuthSession, p as OrganizationWorkspaceSelection, r as AuthOrganization, t as AcceptInvitationInput, u as DriveCredentialInput } from "./types-zEqO1_r2.js";
|
|
2
|
+
import { n as AuthErrorCode, r as AuthErrorStatus, t as AuthError } from "./errors-Crd93Rah.js";
|
|
2
3
|
//#region src/server.d.ts
|
|
3
4
|
interface ServerAuthOptions {
|
|
4
5
|
authOrigin: string;
|
|
@@ -11,11 +12,16 @@ interface ServerAuthOptions {
|
|
|
11
12
|
interface ServerSignOutResult {
|
|
12
13
|
applyCookies(headers: Headers): void;
|
|
13
14
|
}
|
|
15
|
+
interface ServerInvitationAcceptance extends InvitationAcceptance {
|
|
16
|
+
applyCookies(headers: Headers): void;
|
|
17
|
+
}
|
|
14
18
|
interface FinuevaServerAuth {
|
|
19
|
+
acceptInvitation(input: AcceptInvitationInput): Promise<ServerInvitationAcceptance>;
|
|
15
20
|
getSession(): Promise<AuthSession | null>;
|
|
21
|
+
listOrganizations(): Promise<AuthOrganization[]>;
|
|
16
22
|
getDriveCredential(input: DriveCredentialInput): Promise<DriveCredential>;
|
|
17
23
|
signOut(): Promise<ServerSignOutResult>;
|
|
18
24
|
}
|
|
19
25
|
declare function createServerAuth(options: ServerAuthOptions): FinuevaServerAuth;
|
|
20
26
|
//#endregion
|
|
21
|
-
export { AuthError, type AuthErrorCode, type AuthErrorStatus, type AuthSession, type AuthUser, type DriveCredential, type DriveCredentialInput, FinuevaServerAuth, type PersonalWorkspaceSelection, ServerAuthOptions, ServerSignOutResult, createServerAuth };
|
|
27
|
+
export { type AcceptInvitationInput, AuthError, type AuthErrorCode, type AuthErrorStatus, type AuthOrganization, type AuthSession, type AuthUser, type DriveCredential, type DriveCredentialInput, FinuevaServerAuth, type InvitationAcceptance, type OrganizationWorkspaceSelection, type PersonalWorkspaceSelection, ServerAuthOptions, ServerInvitationAcceptance, ServerSignOutResult, type WorkspaceSelection, createServerAuth };
|
package/dist/server.js
CHANGED
|
@@ -1,26 +1,3 @@
|
|
|
1
|
-
//#region src/errors.ts
|
|
2
|
-
const messages = {
|
|
3
|
-
invalid_credentials: "The credentials are invalid.",
|
|
4
|
-
authentication_required: "Authentication is required.",
|
|
5
|
-
request_origin_denied: "The request origin is not allowed.",
|
|
6
|
-
invalid_workspace_selection: "The workspace selection is invalid.",
|
|
7
|
-
credential_rate_limited: "Credential requests are temporarily limited.",
|
|
8
|
-
state_conflict: "The authentication state conflicts with the request.",
|
|
9
|
-
access_denied: "Access is denied.",
|
|
10
|
-
identity_authority_unavailable: "Authentication is temporarily unavailable."
|
|
11
|
-
};
|
|
12
|
-
var AuthError = class extends Error {
|
|
13
|
-
code;
|
|
14
|
-
status;
|
|
15
|
-
retryAfterSeconds;
|
|
16
|
-
constructor(code, status, retryAfterSeconds) {
|
|
17
|
-
super(messages[code]);
|
|
18
|
-
this.name = "AuthError";
|
|
19
|
-
this.code = code;
|
|
20
|
-
this.status = status;
|
|
21
|
-
this.retryAfterSeconds = retryAfterSeconds;
|
|
22
|
-
}
|
|
23
|
-
};
|
|
24
1
|
String.fromCharCode;
|
|
25
2
|
const HASH_RE = /#/g;
|
|
26
3
|
const AMPERSAND_RE = /&/g;
|
|
@@ -459,6 +436,35 @@ function createFetch(globalOptions = {}) {
|
|
|
459
436
|
return $fetch;
|
|
460
437
|
}
|
|
461
438
|
//#endregion
|
|
439
|
+
//#region src/errors.ts
|
|
440
|
+
const messages = {
|
|
441
|
+
invalid_credentials: "The credentials are invalid.",
|
|
442
|
+
authentication_required: "Authentication is required.",
|
|
443
|
+
request_origin_denied: "The request origin is not allowed.",
|
|
444
|
+
invalid_invitation: "The invitation is invalid.",
|
|
445
|
+
invitation_unavailable: "The invitation is not available.",
|
|
446
|
+
invitation_recipient_mismatch: "The invitation cannot be accepted by this account.",
|
|
447
|
+
email_verification_required: "Email verification is required.",
|
|
448
|
+
invalid_workspace_selection: "The workspace selection is invalid.",
|
|
449
|
+
organization_context_too_large: "The organization context is too large.",
|
|
450
|
+
credential_rate_limited: "Credential requests are temporarily limited.",
|
|
451
|
+
state_conflict: "The authentication state conflicts with the request.",
|
|
452
|
+
access_denied: "Access is denied.",
|
|
453
|
+
identity_authority_unavailable: "Authentication is temporarily unavailable."
|
|
454
|
+
};
|
|
455
|
+
var AuthError = class extends Error {
|
|
456
|
+
code;
|
|
457
|
+
status;
|
|
458
|
+
retryAfterSeconds;
|
|
459
|
+
constructor(code, status, retryAfterSeconds) {
|
|
460
|
+
super(messages[code]);
|
|
461
|
+
this.name = "AuthError";
|
|
462
|
+
this.code = code;
|
|
463
|
+
this.status = status;
|
|
464
|
+
this.retryAfterSeconds = retryAfterSeconds;
|
|
465
|
+
}
|
|
466
|
+
};
|
|
467
|
+
//#endregion
|
|
462
468
|
//#region src/shared.ts
|
|
463
469
|
const id = /^[A-Za-z0-9_-]{1,128}$/;
|
|
464
470
|
const email = /^[^\s@]+@[^\s@]+$/;
|
|
@@ -505,6 +511,37 @@ function normalizeDriveCredential(value, now) {
|
|
|
505
511
|
expiresAt: new Date(now + value.expiresIn * 1e3)
|
|
506
512
|
};
|
|
507
513
|
}
|
|
514
|
+
function normalizeOrganizations(value) {
|
|
515
|
+
if (!Array.isArray(value) || value.length >= 100) throw authorityUnavailable();
|
|
516
|
+
const seen = new Set();
|
|
517
|
+
return value.map((organization) => {
|
|
518
|
+
if (!isObject(organization) || !isId(organization.id) || seen.has(organization.id) || typeof organization.name !== "string" || organization.name.length < 1 || typeof organization.slug !== "string" || organization.slug.length < 1) throw authorityUnavailable();
|
|
519
|
+
seen.add(organization.id);
|
|
520
|
+
return {
|
|
521
|
+
id: organization.id,
|
|
522
|
+
name: organization.name,
|
|
523
|
+
slug: organization.slug
|
|
524
|
+
};
|
|
525
|
+
});
|
|
526
|
+
}
|
|
527
|
+
function normalizeInvitationInput(value) {
|
|
528
|
+
if (!isObject(value) || Object.keys(value).length !== 1 || !isId(value.invitationId)) throw new AuthError("invalid_invitation", 422);
|
|
529
|
+
return { invitationId: value.invitationId };
|
|
530
|
+
}
|
|
531
|
+
function normalizeInvitationAcceptance(value, invitationId) {
|
|
532
|
+
if (!isObject(value) || !isObject(value.invitation) || !isObject(value.member) || value.invitation.id !== invitationId || value.invitation.status !== "accepted" || !isId(value.invitation.organizationId) || value.member.organizationId !== value.invitation.organizationId) throw authorityUnavailable();
|
|
533
|
+
return { organizationId: value.invitation.organizationId };
|
|
534
|
+
}
|
|
535
|
+
function normalizeWorkspaceSelection(value) {
|
|
536
|
+
if (!isObject(value)) throw new AuthError("invalid_workspace_selection", 422);
|
|
537
|
+
const keys = Object.keys(value);
|
|
538
|
+
if (value.type === "personal" && keys.length === 1 && keys[0] === "type") return { type: "personal" };
|
|
539
|
+
if (value.type === "organization" && keys.length === 2 && keys.includes("type") && keys.includes("organizationId") && typeof value.organizationId === "string" && id.test(value.organizationId)) return {
|
|
540
|
+
type: "organization",
|
|
541
|
+
organizationId: value.organizationId
|
|
542
|
+
};
|
|
543
|
+
throw new AuthError("invalid_workspace_selection", 422);
|
|
544
|
+
}
|
|
508
545
|
function fromAuthorityError(value, fallbackStatus, retryAfter) {
|
|
509
546
|
const mapped = mapError(isObject(value) && typeof value.code === "string" ? value.code : void 0, fallbackStatus);
|
|
510
547
|
return new AuthError(mapped.code, mapped.status, parseRetryAfter(retryAfter));
|
|
@@ -512,6 +549,23 @@ function fromAuthorityError(value, fallbackStatus, retryAfter) {
|
|
|
512
549
|
function authorityUnavailable() {
|
|
513
550
|
return new AuthError("identity_authority_unavailable", 503);
|
|
514
551
|
}
|
|
552
|
+
function fromOrganizationListError(error) {
|
|
553
|
+
if (error instanceof AuthError && error.status === 401) return new AuthError("authentication_required", 401);
|
|
554
|
+
if (error instanceof AuthError) return error;
|
|
555
|
+
return authorityUnavailable();
|
|
556
|
+
}
|
|
557
|
+
function fromInvitationAuthorityError(value, status) {
|
|
558
|
+
const code = isObject(value) && typeof value.code === "string" ? value.code : void 0;
|
|
559
|
+
if (status === 401 && code === "UNAUTHORIZED") return new AuthError("authentication_required", 401);
|
|
560
|
+
if (status === 403 && (code === "INVALID_ORIGIN" || code === "MISSING_OR_NULL_ORIGIN")) return new AuthError("request_origin_denied", 403);
|
|
561
|
+
if (status === 403 && code === "YOU_ARE_NOT_THE_RECIPIENT_OF_THE_INVITATION") return new AuthError("invitation_recipient_mismatch", 403);
|
|
562
|
+
if (status === 403 && code === "EMAIL_VERIFICATION_REQUIRED_BEFORE_ACCEPTING_OR_REJECTING_INVITATION") return new AuthError("email_verification_required", 403);
|
|
563
|
+
if (status === 400 && (code === "INVITATION_NOT_FOUND" || code === "ORGANIZATION_NOT_FOUND" || code === "TEAM_NOT_FOUND")) return new AuthError("invitation_unavailable", 409);
|
|
564
|
+
return authorityUnavailable();
|
|
565
|
+
}
|
|
566
|
+
function fromInvitationError(error) {
|
|
567
|
+
return error instanceof AuthError ? error : authorityUnavailable();
|
|
568
|
+
}
|
|
515
569
|
function mapError(code, status) {
|
|
516
570
|
if (code === "authentication_required") return {
|
|
517
571
|
code,
|
|
@@ -525,6 +579,10 @@ function mapError(code, status) {
|
|
|
525
579
|
code,
|
|
526
580
|
status: 422
|
|
527
581
|
};
|
|
582
|
+
if (code === "organization_context_too_large") return {
|
|
583
|
+
code,
|
|
584
|
+
status: 422
|
|
585
|
+
};
|
|
528
586
|
if (code === "credential_rate_limited") return {
|
|
529
587
|
code,
|
|
530
588
|
status: 429
|
|
@@ -577,6 +635,9 @@ function isObject(value) {
|
|
|
577
635
|
//#region src/http.ts
|
|
578
636
|
const MAX_RESPONSE_BYTES = 64 * 1024;
|
|
579
637
|
async function requestJson(url, options) {
|
|
638
|
+
return (await requestJsonResponse(url, options)).value;
|
|
639
|
+
}
|
|
640
|
+
async function requestJsonResponse(url, options) {
|
|
580
641
|
let response;
|
|
581
642
|
try {
|
|
582
643
|
response = await createFetch({ fetch: options.fetch }).raw(url, {
|
|
@@ -587,6 +648,7 @@ async function requestJson(url, options) {
|
|
|
587
648
|
retry: 0,
|
|
588
649
|
timeout: options.timeoutMs,
|
|
589
650
|
redirect: "manual",
|
|
651
|
+
signal: options.signal,
|
|
590
652
|
responseType: "stream",
|
|
591
653
|
ignoreResponseError: true
|
|
592
654
|
});
|
|
@@ -597,9 +659,12 @@ async function requestJson(url, options) {
|
|
|
597
659
|
if (response.status >= 300 || response.status < 200 || contentType !== "application/json") {
|
|
598
660
|
const body = contentType === "application/json" ? await readJson(response) : void 0;
|
|
599
661
|
await response.body?.cancel();
|
|
600
|
-
throw fromAuthorityError(body, response.status, response.headers.get("retry-after"));
|
|
662
|
+
throw (options.mapError ?? fromAuthorityError)(body, response.status, response.headers.get("retry-after"));
|
|
601
663
|
}
|
|
602
|
-
return
|
|
664
|
+
return {
|
|
665
|
+
value: await readJson(response),
|
|
666
|
+
headers: response.headers
|
|
667
|
+
};
|
|
603
668
|
}
|
|
604
669
|
async function readJson(response) {
|
|
605
670
|
const length = response.headers.get("content-length");
|
|
@@ -652,6 +717,32 @@ function createServerAuth(options) {
|
|
|
652
717
|
origin: appOrigin
|
|
653
718
|
});
|
|
654
719
|
return {
|
|
720
|
+
async acceptInvitation(input) {
|
|
721
|
+
const invitation = normalizeInvitationInput(input);
|
|
722
|
+
try {
|
|
723
|
+
const result = await requestJsonResponse(joinURL(authOrigin, "api/v1/auth/organization/accept-invitation"), {
|
|
724
|
+
fetch: fetchImpl,
|
|
725
|
+
timeoutMs,
|
|
726
|
+
method: "POST",
|
|
727
|
+
headers: {
|
|
728
|
+
...authHeaders(),
|
|
729
|
+
"content-type": "application/json; charset=utf-8"
|
|
730
|
+
},
|
|
731
|
+
body: invitation,
|
|
732
|
+
mapError: fromInvitationAuthorityError
|
|
733
|
+
});
|
|
734
|
+
const acceptance = normalizeInvitationAcceptance(result.value, invitation.invitationId);
|
|
735
|
+
const cookies = responseCookies(result.headers);
|
|
736
|
+
return {
|
|
737
|
+
...acceptance,
|
|
738
|
+
applyCookies(headers) {
|
|
739
|
+
applyCookies(cookies, headers);
|
|
740
|
+
}
|
|
741
|
+
};
|
|
742
|
+
} catch (error) {
|
|
743
|
+
throw fromInvitationError(error);
|
|
744
|
+
}
|
|
745
|
+
},
|
|
655
746
|
async getSession() {
|
|
656
747
|
return normalizeSession(await requestJson(joinURL(authOrigin, "api/v1/auth/get-session"), {
|
|
657
748
|
fetch: fetchImpl,
|
|
@@ -660,8 +751,20 @@ function createServerAuth(options) {
|
|
|
660
751
|
headers: { cookie }
|
|
661
752
|
}));
|
|
662
753
|
},
|
|
754
|
+
async listOrganizations() {
|
|
755
|
+
try {
|
|
756
|
+
return normalizeOrganizations(await requestJson(joinURL(authOrigin, "api/v1/auth/organization/list"), {
|
|
757
|
+
fetch: fetchImpl,
|
|
758
|
+
timeoutMs,
|
|
759
|
+
method: "GET",
|
|
760
|
+
headers: authHeaders()
|
|
761
|
+
}));
|
|
762
|
+
} catch (error) {
|
|
763
|
+
throw fromOrganizationListError(error);
|
|
764
|
+
}
|
|
765
|
+
},
|
|
663
766
|
async getDriveCredential(input) {
|
|
664
|
-
|
|
767
|
+
const workspace = normalizeWorkspaceSelection(input?.workspace);
|
|
665
768
|
return normalizeDriveCredential(await requestJson(joinURL(authOrigin, "api/v1/auth/drive-credential"), {
|
|
666
769
|
fetch: fetchImpl,
|
|
667
770
|
timeoutMs,
|
|
@@ -670,7 +773,7 @@ function createServerAuth(options) {
|
|
|
670
773
|
...authHeaders(),
|
|
671
774
|
"content-type": "application/json; charset=utf-8"
|
|
672
775
|
},
|
|
673
|
-
body: { workspace
|
|
776
|
+
body: { workspace }
|
|
674
777
|
}), now());
|
|
675
778
|
},
|
|
676
779
|
async signOut() {
|
|
@@ -689,15 +792,21 @@ function createServerAuth(options) {
|
|
|
689
792
|
await response.body?.cancel();
|
|
690
793
|
throw authorityUnavailable();
|
|
691
794
|
}
|
|
692
|
-
const
|
|
693
|
-
const cookies = getSetCookie ? getSetCookie.call(response.headers) : [response.headers.get("set-cookie")].filter(Boolean);
|
|
795
|
+
const cookies = responseCookies(response.headers);
|
|
694
796
|
await response.body?.cancel();
|
|
695
797
|
return { applyCookies(headers) {
|
|
696
|
-
|
|
798
|
+
applyCookies(cookies, headers);
|
|
697
799
|
} };
|
|
698
800
|
}
|
|
699
801
|
};
|
|
700
802
|
}
|
|
803
|
+
function responseCookies(headers) {
|
|
804
|
+
const getSetCookie = headers.getSetCookie;
|
|
805
|
+
return getSetCookie ? getSetCookie.call(headers) : [headers.get("set-cookie")].filter((value) => !!value);
|
|
806
|
+
}
|
|
807
|
+
function applyCookies(cookies, headers) {
|
|
808
|
+
for (const value of cookies) headers.append("set-cookie", value);
|
|
809
|
+
}
|
|
701
810
|
function authCookieHeader(value) {
|
|
702
811
|
if (!value) return "";
|
|
703
812
|
return value.split(";").map((cookie) => cookie.trim()).filter((cookie) => {
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
//#region src/types.d.ts
|
|
2
|
+
interface AuthUser {
|
|
3
|
+
id: string;
|
|
4
|
+
name: string;
|
|
5
|
+
email: string;
|
|
6
|
+
emailVerified: boolean;
|
|
7
|
+
image: string | null;
|
|
8
|
+
}
|
|
9
|
+
interface AuthSession {
|
|
10
|
+
id: string;
|
|
11
|
+
expiresAt: Date;
|
|
12
|
+
user: AuthUser;
|
|
13
|
+
}
|
|
14
|
+
interface AuthOrganization {
|
|
15
|
+
id: string;
|
|
16
|
+
name: string;
|
|
17
|
+
slug: string;
|
|
18
|
+
}
|
|
19
|
+
interface AcceptInvitationInput {
|
|
20
|
+
invitationId: string;
|
|
21
|
+
}
|
|
22
|
+
interface InvitationAcceptance {
|
|
23
|
+
organizationId: string;
|
|
24
|
+
}
|
|
25
|
+
type AuthState = {
|
|
26
|
+
status: "loading";
|
|
27
|
+
} | {
|
|
28
|
+
status: "cached";
|
|
29
|
+
session: AuthSession;
|
|
30
|
+
authoritative: false;
|
|
31
|
+
} | {
|
|
32
|
+
status: "authenticated";
|
|
33
|
+
session: AuthSession;
|
|
34
|
+
authoritative: true;
|
|
35
|
+
} | {
|
|
36
|
+
status: "unauthenticated";
|
|
37
|
+
session: null;
|
|
38
|
+
authoritative: true;
|
|
39
|
+
} | {
|
|
40
|
+
status: "unavailable";
|
|
41
|
+
session: AuthSession | null;
|
|
42
|
+
authoritative: false;
|
|
43
|
+
};
|
|
44
|
+
interface AuthPersistenceDriver {
|
|
45
|
+
getItem(key: string): string | null | Promise<string | null>;
|
|
46
|
+
setItem(key: string, value: string): void | Promise<void>;
|
|
47
|
+
removeItem(key: string): void | Promise<void>;
|
|
48
|
+
}
|
|
49
|
+
type AuthPersistence = "local" | "session" | "memory" | AuthPersistenceDriver;
|
|
50
|
+
interface PersonalWorkspaceSelection {
|
|
51
|
+
type: "personal";
|
|
52
|
+
}
|
|
53
|
+
interface OrganizationWorkspaceSelection {
|
|
54
|
+
type: "organization";
|
|
55
|
+
organizationId: string;
|
|
56
|
+
}
|
|
57
|
+
type WorkspaceSelection = PersonalWorkspaceSelection | OrganizationWorkspaceSelection;
|
|
58
|
+
interface DriveCredential {
|
|
59
|
+
tokenType: "Bearer";
|
|
60
|
+
token: string;
|
|
61
|
+
expiresAt: Date;
|
|
62
|
+
}
|
|
63
|
+
interface SignInInput {
|
|
64
|
+
email: string;
|
|
65
|
+
password: string;
|
|
66
|
+
}
|
|
67
|
+
interface DriveCredentialInput {
|
|
68
|
+
workspace: WorkspaceSelection;
|
|
69
|
+
forceRefresh?: boolean;
|
|
70
|
+
}
|
|
71
|
+
interface AuthClientOptions {
|
|
72
|
+
authOrigin: string;
|
|
73
|
+
appOrigin: string;
|
|
74
|
+
fetch?: typeof globalThis.fetch;
|
|
75
|
+
now?: () => number;
|
|
76
|
+
persistence?: AuthPersistence;
|
|
77
|
+
timeoutMs?: number;
|
|
78
|
+
}
|
|
79
|
+
interface FinuevaAuthClient {
|
|
80
|
+
acceptInvitation(input: AcceptInvitationInput): Promise<InvitationAcceptance>;
|
|
81
|
+
getSession(): Promise<AuthSession | null>;
|
|
82
|
+
listOrganizations(): Promise<AuthOrganization[]>;
|
|
83
|
+
signIn(input: SignInInput): Promise<AuthSession>;
|
|
84
|
+
signOut(): Promise<void>;
|
|
85
|
+
getDriveCredential(input: DriveCredentialInput): Promise<DriveCredential>;
|
|
86
|
+
onAuthStateChange(listener: (state: AuthState) => void): () => void;
|
|
87
|
+
onSessionChange(listener: (session: AuthSession | null) => void): () => void;
|
|
88
|
+
}
|
|
89
|
+
//#endregion
|
|
90
|
+
export { AuthPersistenceDriver as a, AuthUser as c, FinuevaAuthClient as d, InvitationAcceptance as f, WorkspaceSelection as g, SignInInput as h, AuthPersistence as i, DriveCredential as l, PersonalWorkspaceSelection as m, AuthClientOptions as n, AuthSession as o, OrganizationWorkspaceSelection as p, AuthOrganization as r, AuthState as s, AcceptInvitationInput as t, DriveCredentialInput as u };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@finueva/auth",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Public browser and server SDK for Finueva Auth",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -18,6 +18,10 @@
|
|
|
18
18
|
"./server": {
|
|
19
19
|
"types": "./dist/server.d.ts",
|
|
20
20
|
"import": "./dist/server.js"
|
|
21
|
+
},
|
|
22
|
+
"./device": {
|
|
23
|
+
"types": "./dist/device.d.ts",
|
|
24
|
+
"import": "./dist/device.js"
|
|
21
25
|
}
|
|
22
26
|
},
|
|
23
27
|
"files": [
|
|
@@ -38,20 +42,24 @@
|
|
|
38
42
|
"coverage": "vitest run --coverage",
|
|
39
43
|
"lint": "eslint .",
|
|
40
44
|
"test": "pnpm test:unit && pnpm build && pnpm test:package",
|
|
45
|
+
"test:composition": "node scripts/test-composition.mjs",
|
|
41
46
|
"test:package": "node scripts/test-package.mjs",
|
|
42
47
|
"test:unit": "vitest run",
|
|
43
48
|
"typecheck": "tsc --noEmit"
|
|
44
49
|
},
|
|
45
50
|
"devDependencies": {
|
|
51
|
+
"@chiballc/utils": "2.2.22",
|
|
46
52
|
"@types/node": "24.13.3",
|
|
47
53
|
"@vitest/coverage-v8": "4.1.10",
|
|
48
|
-
"@chiballc/utils": "2.2.22",
|
|
49
54
|
"better-auth": "1.6.22",
|
|
55
|
+
"miniflare": "4.20260722.0",
|
|
50
56
|
"ofetch": "1.5.1",
|
|
57
|
+
"playwright": "1.62.0",
|
|
51
58
|
"rolldown": "1.2.0",
|
|
52
59
|
"rolldown-plugin-dts": "0.27.14",
|
|
53
60
|
"typescript": "5.9.2",
|
|
54
61
|
"ufo": "1.6.4",
|
|
62
|
+
"unstorage": "1.17.5",
|
|
55
63
|
"vitest": "4.1.10"
|
|
56
64
|
}
|
|
57
65
|
}
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
//#region src/types.d.ts
|
|
2
|
-
interface AuthUser {
|
|
3
|
-
id: string;
|
|
4
|
-
name: string;
|
|
5
|
-
email: string;
|
|
6
|
-
emailVerified: boolean;
|
|
7
|
-
image: string | null;
|
|
8
|
-
}
|
|
9
|
-
interface AuthSession {
|
|
10
|
-
id: string;
|
|
11
|
-
expiresAt: Date;
|
|
12
|
-
user: AuthUser;
|
|
13
|
-
}
|
|
14
|
-
interface PersonalWorkspaceSelection {
|
|
15
|
-
type: "personal";
|
|
16
|
-
}
|
|
17
|
-
interface DriveCredential {
|
|
18
|
-
tokenType: "Bearer";
|
|
19
|
-
token: string;
|
|
20
|
-
expiresAt: Date;
|
|
21
|
-
}
|
|
22
|
-
interface SignInInput {
|
|
23
|
-
email: string;
|
|
24
|
-
password: string;
|
|
25
|
-
}
|
|
26
|
-
interface DriveCredentialInput {
|
|
27
|
-
workspace: PersonalWorkspaceSelection;
|
|
28
|
-
forceRefresh?: boolean;
|
|
29
|
-
}
|
|
30
|
-
interface AuthClientOptions {
|
|
31
|
-
authOrigin: string;
|
|
32
|
-
appOrigin: string;
|
|
33
|
-
fetch?: typeof globalThis.fetch;
|
|
34
|
-
now?: () => number;
|
|
35
|
-
timeoutMs?: number;
|
|
36
|
-
}
|
|
37
|
-
interface FinuevaAuthClient {
|
|
38
|
-
getSession(): Promise<AuthSession | null>;
|
|
39
|
-
signIn(input: SignInInput): Promise<AuthSession>;
|
|
40
|
-
signOut(): Promise<void>;
|
|
41
|
-
getDriveCredential(input: DriveCredentialInput): Promise<DriveCredential>;
|
|
42
|
-
onSessionChange(listener: (session: AuthSession | null) => void): () => void;
|
|
43
|
-
}
|
|
44
|
-
//#endregion
|
|
45
|
-
//#region src/errors.d.ts
|
|
46
|
-
type AuthErrorCode = "invalid_credentials" | "authentication_required" | "request_origin_denied" | "invalid_workspace_selection" | "credential_rate_limited" | "state_conflict" | "access_denied" | "identity_authority_unavailable";
|
|
47
|
-
type AuthErrorStatus = 401 | 403 | 409 | 422 | 429 | 503;
|
|
48
|
-
declare class AuthError extends Error {
|
|
49
|
-
readonly code: AuthErrorCode;
|
|
50
|
-
readonly status: AuthErrorStatus;
|
|
51
|
-
readonly retryAfterSeconds?: number;
|
|
52
|
-
constructor(code: AuthErrorCode, status: AuthErrorStatus, retryAfterSeconds?: number);
|
|
53
|
-
}
|
|
54
|
-
//#endregion
|
|
55
|
-
export { AuthSession as a, DriveCredentialInput as c, SignInInput as d, AuthClientOptions as i, FinuevaAuthClient as l, AuthErrorCode as n, AuthUser as o, AuthErrorStatus as r, DriveCredential as s, AuthError as t, PersonalWorkspaceSelection as u };
|