@structured-id/ui-core 0.1.5
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/LICENSE +661 -0
- package/README.md +47 -0
- package/dist/browser-vp/index.cjs +349 -0
- package/dist/browser-vp/index.d.cts +287 -0
- package/dist/browser-vp/index.d.ts +287 -0
- package/dist/browser-vp/index.js +349 -0
- package/dist/chunk-C3Q766CY.cjs +125 -0
- package/dist/chunk-J5YXRXB5.js +125 -0
- package/dist/index.cjs +19360 -0
- package/dist/index.d.cts +9536 -0
- package/dist/index.d.ts +9536 -0
- package/dist/index.js +19360 -0
- package/dist/storage-4CB2JTLW.cjs +22 -0
- package/dist/storage-THRWREZP.js +22 -0
- package/package.json +93 -0
- package/src/browser-vp/crypto.ts +254 -0
- package/src/browser-vp/index.test.ts +10 -0
- package/src/browser-vp/index.ts +118 -0
- package/src/browser-vp/prf.ts +181 -0
- package/src/browser-vp/storage.test.ts +9 -0
- package/src/browser-vp/storage.ts +165 -0
- package/src/browser-vp/types.ts +97 -0
- package/src/browser-vp/vp.test.ts +43 -0
- package/src/browser-vp/vp.ts +113 -0
- package/src/components/SidAvatar.vue +106 -0
- package/src/components/SidConfirmDialog.vue +125 -0
- package/src/components/SidStatusBadge.vue +71 -0
- package/src/components/index.ts +5 -0
- package/src/composables/index.ts +10 -0
- package/src/composables/useAuth.ts +40 -0
- package/src/composables/useBffAuth.ts +147 -0
- package/src/composables/useGrpc.test.ts +196 -0
- package/src/composables/useGrpc.ts +120 -0
- package/src/composables/useSession.ts +80 -0
- package/src/generated/google/api/http.ts +687 -0
- package/src/generated/google/protobuf/descriptor.ts +4865 -0
- package/src/generated/google/protobuf/duration.ts +230 -0
- package/src/generated/google/protobuf/empty.ts +94 -0
- package/src/generated/google/protobuf/struct.ts +484 -0
- package/src/generated/google/protobuf/timestamp.ts +287 -0
- package/src/generated/sid/v1/account/account.client.ts +527 -0
- package/src/generated/sid/v1/account/account.ts +3261 -0
- package/src/generated/sid/v1/admin/admin.client.ts +136 -0
- package/src/generated/sid/v1/admin/admin.ts +846 -0
- package/src/generated/sid/v1/admin/admin_roles.client.ts +181 -0
- package/src/generated/sid/v1/admin/admin_roles.ts +1606 -0
- package/src/generated/sid/v1/admin/analytics.client.ts +106 -0
- package/src/generated/sid/v1/admin/analytics.ts +1017 -0
- package/src/generated/sid/v1/admin/branding.client.ts +166 -0
- package/src/generated/sid/v1/admin/branding.ts +1906 -0
- package/src/generated/sid/v1/admin/enrollment.client.ts +165 -0
- package/src/generated/sid/v1/admin/enrollment.ts +1704 -0
- package/src/generated/sid/v1/admin/events.client.ts +195 -0
- package/src/generated/sid/v1/admin/events.ts +1900 -0
- package/src/generated/sid/v1/admin/flow.client.ts +183 -0
- package/src/generated/sid/v1/admin/flow.ts +1552 -0
- package/src/generated/sid/v1/admin/keys.client.ts +107 -0
- package/src/generated/sid/v1/admin/keys.ts +931 -0
- package/src/generated/sid/v1/admin/login_experience.client.ts +160 -0
- package/src/generated/sid/v1/admin/login_experience.ts +1061 -0
- package/src/generated/sid/v1/admin/migration.client.ts +127 -0
- package/src/generated/sid/v1/admin/migration.ts +1948 -0
- package/src/generated/sid/v1/admin/notifications.client.ts +128 -0
- package/src/generated/sid/v1/admin/notifications.ts +1332 -0
- package/src/generated/sid/v1/admin/operations.client.ts +241 -0
- package/src/generated/sid/v1/admin/operations.ts +2648 -0
- package/src/generated/sid/v1/admin/organizations.client.ts +57 -0
- package/src/generated/sid/v1/admin/organizations.ts +349 -0
- package/src/generated/sid/v1/admin/scopes.client.ts +171 -0
- package/src/generated/sid/v1/admin/scopes.ts +1324 -0
- package/src/generated/sid/v1/admin/security.client.ts +412 -0
- package/src/generated/sid/v1/admin/security.ts +4086 -0
- package/src/generated/sid/v1/admin/sessions.client.ts +114 -0
- package/src/generated/sid/v1/admin/sessions.ts +923 -0
- package/src/generated/sid/v1/admin/settings.client.ts +340 -0
- package/src/generated/sid/v1/admin/settings.ts +2395 -0
- package/src/generated/sid/v1/admin/user_profile.client.ts +57 -0
- package/src/generated/sid/v1/admin/user_profile.ts +730 -0
- package/src/generated/sid/v1/admin/webhooks.client.ts +269 -0
- package/src/generated/sid/v1/admin/webhooks.ts +2804 -0
- package/src/generated/sid/v1/attestation/attestation.client.ts +115 -0
- package/src/generated/sid/v1/attestation/attestation.ts +813 -0
- package/src/generated/sid/v1/authn/auth.client.ts +900 -0
- package/src/generated/sid/v1/authn/auth.ts +9287 -0
- package/src/generated/sid/v1/authn/flows.client.ts +413 -0
- package/src/generated/sid/v1/authn/flows.ts +3217 -0
- package/src/generated/sid/v1/authz/authz.client.ts +459 -0
- package/src/generated/sid/v1/authz/authz.ts +5343 -0
- package/src/generated/sid/v1/authz/governance.client.ts +102 -0
- package/src/generated/sid/v1/authz/governance.ts +818 -0
- package/src/generated/sid/v1/common/errors.ts +184 -0
- package/src/generated/sid/v1/common/pagination.ts +152 -0
- package/src/generated/sid/v1/common/transport.ts +227 -0
- package/src/generated/sid/v1/common/types.ts +151 -0
- package/src/generated/sid/v1/events/event_stream.client.ts +67 -0
- package/src/generated/sid/v1/events/event_stream.ts +374 -0
- package/src/generated/sid/v1/federation/upstream.client.ts +142 -0
- package/src/generated/sid/v1/federation/upstream.ts +1736 -0
- package/src/generated/sid/v1/identity/identity.client.ts +467 -0
- package/src/generated/sid/v1/identity/identity.ts +5613 -0
- package/src/generated/sid/v1/machine/machine_user.client.ts +219 -0
- package/src/generated/sid/v1/machine/machine_user.ts +2400 -0
- package/src/generated/sid/v1/machine/pat.client.ts +147 -0
- package/src/generated/sid/v1/machine/pat.ts +1268 -0
- package/src/generated/sid/v1/projects/projects.client.ts +286 -0
- package/src/generated/sid/v1/projects/projects.ts +2714 -0
- package/src/generated/sid/v1/scim/scim.client.ts +274 -0
- package/src/generated/sid/v1/scim/scim.ts +3043 -0
- package/src/generated/sid/v1/test/test.client.ts +232 -0
- package/src/generated/sid/v1/test/test.ts +1136 -0
- package/src/i18n/index.ts +40 -0
- package/src/index.ts +157 -0
- package/src/profile/auth.ts +15 -0
- package/src/profile/components/ConsentManager.vue +88 -0
- package/src/profile/components/ProfileEditor.vue +146 -0
- package/src/profile/components/SecuritySettings.vue +170 -0
- package/src/profile/components/SessionList.vue +100 -0
- package/src/profile/components/SidLoginForm.test.ts +80 -0
- package/src/profile/components/SidLoginForm.vue +230 -0
- package/src/profile/components/SidMfaChallenge.test.ts +127 -0
- package/src/profile/components/SidMfaChallenge.vue +243 -0
- package/src/profile/components/SidRegistrationForm.test.ts +79 -0
- package/src/profile/components/SidRegistrationForm.vue +317 -0
- package/src/profile/components/index.ts +11 -0
- package/src/profile/composables/index.ts +6 -0
- package/src/profile/composables/useAccountApi.ts +203 -0
- package/src/profile/composables/useAuthApi.opaque.test.ts +140 -0
- package/src/profile/composables/useAuthApi.ts +617 -0
- package/src/profile/composables/useIdentityApi.ts +123 -0
- package/src/profile/composables/useLoginSuccess.test.ts +112 -0
- package/src/profile/composables/useLoginSuccess.ts +65 -0
- package/src/profile/composables/useOpaqueAuth.test.ts +290 -0
- package/src/profile/composables/useOpaqueAuth.ts +191 -0
- package/src/profile/composables/useSecurityLevel.test.ts +198 -0
- package/src/profile/composables/useSecurityLevel.ts +324 -0
- package/src/profile/index.ts +18 -0
- package/src/quasar/SidPrincipalInput.vue +209 -0
- package/src/quasar/index.ts +8 -0
- package/src/stores/auth.test.ts +83 -0
- package/src/stores/auth.ts +92 -0
- package/src/stores/index.ts +1 -0
- package/src/transport/adaptive.test.ts +728 -0
- package/src/transport/adaptive.ts +308 -0
- package/src/transport/framing.test.ts +227 -0
- package/src/transport/framing.ts +98 -0
- package/src/transport/webtransport.test.ts +728 -0
- package/src/transport/webtransport.ts +323 -0
- package/src/types/auth.ts +58 -0
- package/src/types/index.ts +1 -0
- package/src/utils/formatters.test.ts +26 -0
- package/src/utils/formatters.ts +69 -0
- package/src/utils/index.ts +16 -0
- package/src/utils/normalizePrincipal.test.ts +188 -0
- package/src/utils/normalizePrincipal.ts +159 -0
- package/src/utils/validators.test.ts +75 -0
- package/src/utils/validators.ts +36 -0
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Profile account API composable.
|
|
3
|
+
*
|
|
4
|
+
* Wraps AccountServiceClient proto calls with Bearer auth.
|
|
5
|
+
* Covers: consents, activity, linked accounts, app launcher, passwordless.
|
|
6
|
+
*/
|
|
7
|
+
import {
|
|
8
|
+
getTransport,
|
|
9
|
+
AccountServiceClient,
|
|
10
|
+
type ConsentInfo,
|
|
11
|
+
type ClaimConsent,
|
|
12
|
+
type GetConsentDetailResponse,
|
|
13
|
+
type ActivityEvent,
|
|
14
|
+
type ListActivityEventsResponse,
|
|
15
|
+
type LinkedAccount,
|
|
16
|
+
type ListLinkedAccountsResponse,
|
|
17
|
+
type LinkAccountResponse,
|
|
18
|
+
type ReauthenticateLinkResponse,
|
|
19
|
+
type AvailableApp,
|
|
20
|
+
type LaunchAppResponse,
|
|
21
|
+
type PasswordlessStatus,
|
|
22
|
+
type DisablePasswordlessResponse,
|
|
23
|
+
ConsentStatus,
|
|
24
|
+
ClaimType,
|
|
25
|
+
ClaimConsentStatus,
|
|
26
|
+
ActivityEventStatus,
|
|
27
|
+
LinkedAccountTrustCategory,
|
|
28
|
+
LinkedAccountStatus,
|
|
29
|
+
Timestamp,
|
|
30
|
+
} from "../../index";
|
|
31
|
+
import { authMeta } from "../auth";
|
|
32
|
+
|
|
33
|
+
function client(): AccountServiceClient {
|
|
34
|
+
return new AccountServiceClient(getTransport());
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// ── Consents ──
|
|
38
|
+
|
|
39
|
+
export type { ConsentInfo, ClaimConsent, GetConsentDetailResponse };
|
|
40
|
+
|
|
41
|
+
export async function listConsents(): Promise<ConsentInfo[]> {
|
|
42
|
+
const { response } = await client().listConsents({}, { meta: authMeta() });
|
|
43
|
+
return response.consents;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export async function getConsentDetail(
|
|
47
|
+
siteId: string,
|
|
48
|
+
): Promise<GetConsentDetailResponse> {
|
|
49
|
+
const { response } = await client().getConsentDetail(
|
|
50
|
+
{ siteId },
|
|
51
|
+
{ meta: authMeta() },
|
|
52
|
+
);
|
|
53
|
+
return response;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export async function updateClaimConsent(
|
|
57
|
+
siteId: string,
|
|
58
|
+
claimName: string,
|
|
59
|
+
grant: boolean,
|
|
60
|
+
): Promise<void> {
|
|
61
|
+
await client().updateClaimConsent(
|
|
62
|
+
{ siteId, claimName, grant },
|
|
63
|
+
{ meta: authMeta() },
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export async function disconnectSite(siteId: string): Promise<void> {
|
|
68
|
+
await client().disconnectSite({ siteId }, { meta: authMeta() });
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// ── Activity ──
|
|
72
|
+
|
|
73
|
+
export type { ActivityEvent, ListActivityEventsResponse };
|
|
74
|
+
|
|
75
|
+
export interface ActivityFilters {
|
|
76
|
+
eventTypes?: string[];
|
|
77
|
+
applicationId?: string;
|
|
78
|
+
statusFilter?: ActivityEventStatus;
|
|
79
|
+
dateFrom?: Date;
|
|
80
|
+
dateTo?: Date;
|
|
81
|
+
search?: string;
|
|
82
|
+
pageSize?: number;
|
|
83
|
+
pageToken?: string;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export async function listActivityEvents(
|
|
87
|
+
filters: ActivityFilters = {},
|
|
88
|
+
): Promise<ListActivityEventsResponse> {
|
|
89
|
+
const { response } = await client().listActivityEvents(
|
|
90
|
+
{
|
|
91
|
+
eventTypes: filters.eventTypes ?? [],
|
|
92
|
+
applicationId: filters.applicationId,
|
|
93
|
+
statusFilter: filters.statusFilter,
|
|
94
|
+
dateFrom: filters.dateFrom
|
|
95
|
+
? Timestamp.fromDate(filters.dateFrom)
|
|
96
|
+
: undefined,
|
|
97
|
+
dateTo: filters.dateTo ? Timestamp.fromDate(filters.dateTo) : undefined,
|
|
98
|
+
search: filters.search,
|
|
99
|
+
pageSize: filters.pageSize ?? 20,
|
|
100
|
+
pageToken: filters.pageToken ?? "",
|
|
101
|
+
},
|
|
102
|
+
{ meta: authMeta() },
|
|
103
|
+
);
|
|
104
|
+
return response;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export async function getActivityEventDetail(
|
|
108
|
+
eventId: string,
|
|
109
|
+
): Promise<ActivityEvent> {
|
|
110
|
+
const { response } = await client().getActivityEventDetail(
|
|
111
|
+
{ eventId },
|
|
112
|
+
{ meta: authMeta() },
|
|
113
|
+
);
|
|
114
|
+
return response;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export async function reportSuspiciousEvent(
|
|
118
|
+
eventId: string,
|
|
119
|
+
description?: string,
|
|
120
|
+
): Promise<void> {
|
|
121
|
+
await client().reportSuspiciousEvent(
|
|
122
|
+
{ eventId, description },
|
|
123
|
+
{ meta: authMeta() },
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// ── Linked Accounts ──
|
|
128
|
+
|
|
129
|
+
export type { LinkedAccount, ListLinkedAccountsResponse };
|
|
130
|
+
|
|
131
|
+
export async function listLinkedAccounts(): Promise<ListLinkedAccountsResponse> {
|
|
132
|
+
const { response } = await client().listLinkedAccounts({}, { meta: authMeta() });
|
|
133
|
+
return response;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export async function linkAccount(
|
|
137
|
+
providerId: string,
|
|
138
|
+
redirectUri: string,
|
|
139
|
+
): Promise<LinkAccountResponse> {
|
|
140
|
+
const { response } = await client().linkAccount(
|
|
141
|
+
{ providerId, redirectUri },
|
|
142
|
+
{ meta: authMeta() },
|
|
143
|
+
);
|
|
144
|
+
return response;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
export async function unlinkAccount(linkedAccountId: string): Promise<void> {
|
|
148
|
+
await client().unlinkAccount({ linkedAccountId }, { meta: authMeta() });
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export async function reauthenticateLink(
|
|
152
|
+
linkedAccountId: string,
|
|
153
|
+
redirectUri: string,
|
|
154
|
+
): Promise<ReauthenticateLinkResponse> {
|
|
155
|
+
const { response } = await client().reauthenticateLink(
|
|
156
|
+
{ linkedAccountId, redirectUri },
|
|
157
|
+
{ meta: authMeta() },
|
|
158
|
+
);
|
|
159
|
+
return response;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// ── App Launcher ──
|
|
163
|
+
|
|
164
|
+
export type { AvailableApp, PasswordlessStatus, DisablePasswordlessResponse };
|
|
165
|
+
|
|
166
|
+
export async function listAvailableApps(): Promise<AvailableApp[]> {
|
|
167
|
+
const { response } = await client().listAvailableApps({}, { meta: authMeta() });
|
|
168
|
+
return response.apps;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
export async function launchApp(appId: string): Promise<LaunchAppResponse> {
|
|
172
|
+
const { response } = await client().launchApp({ appId }, { meta: authMeta() });
|
|
173
|
+
return response;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// ── Passwordless ──
|
|
177
|
+
|
|
178
|
+
export async function getPasswordlessStatus(): Promise<PasswordlessStatus> {
|
|
179
|
+
const { response } = await client().getPasswordlessStatus(
|
|
180
|
+
{},
|
|
181
|
+
{ meta: authMeta() },
|
|
182
|
+
);
|
|
183
|
+
return response;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
export async function enablePasswordless(): Promise<void> {
|
|
187
|
+
await client().enablePasswordless({}, { meta: authMeta() });
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
export async function disablePasswordless(): Promise<DisablePasswordlessResponse> {
|
|
191
|
+
const { response } = await client().disablePasswordless({}, { meta: authMeta() });
|
|
192
|
+
return response;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// Re-export enums
|
|
196
|
+
export {
|
|
197
|
+
ConsentStatus,
|
|
198
|
+
ClaimType,
|
|
199
|
+
ClaimConsentStatus,
|
|
200
|
+
ActivityEventStatus,
|
|
201
|
+
LinkedAccountTrustCategory,
|
|
202
|
+
LinkedAccountStatus,
|
|
203
|
+
};
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { describe, it, expect, vi, beforeEach } from "vitest";
|
|
2
|
+
import {
|
|
3
|
+
opaqueLoginStart,
|
|
4
|
+
opaqueLoginFinish,
|
|
5
|
+
opaqueRegistrationStart,
|
|
6
|
+
opaqueRegistrationFinish,
|
|
7
|
+
} from "./useAuthApi";
|
|
8
|
+
|
|
9
|
+
// Mock the gRPC transport + AuthServiceClient
|
|
10
|
+
const mockOpaqueLoginStart = vi.fn();
|
|
11
|
+
const mockOpaqueLoginFinish = vi.fn();
|
|
12
|
+
const mockOpaqueRegistrationStart = vi.fn();
|
|
13
|
+
const mockOpaqueRegistrationFinish = vi.fn();
|
|
14
|
+
|
|
15
|
+
vi.mock("../../index", () => ({
|
|
16
|
+
getTransport: vi.fn(),
|
|
17
|
+
AuthServiceClient: vi.fn().mockImplementation(() => ({
|
|
18
|
+
opaqueLoginStart: mockOpaqueLoginStart,
|
|
19
|
+
opaqueLoginFinish: mockOpaqueLoginFinish,
|
|
20
|
+
opaqueRegistrationStart: mockOpaqueRegistrationStart,
|
|
21
|
+
opaqueRegistrationFinish: mockOpaqueRegistrationFinish,
|
|
22
|
+
})),
|
|
23
|
+
}));
|
|
24
|
+
|
|
25
|
+
// authMeta needs to be mocked since it uses useAuth() which needs Vue context
|
|
26
|
+
vi.mock("../auth", () => ({
|
|
27
|
+
authMeta: () => ({}),
|
|
28
|
+
}));
|
|
29
|
+
|
|
30
|
+
describe("OPAQUE gRPC wrappers", () => {
|
|
31
|
+
beforeEach(() => {
|
|
32
|
+
vi.clearAllMocks();
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
describe("opaqueLoginStart", () => {
|
|
36
|
+
it("sends principal and credentialRequest, returns response", async () => {
|
|
37
|
+
const expected = {
|
|
38
|
+
credentialResponse: new Uint8Array([1, 2, 3]),
|
|
39
|
+
serverLoginState: "state-123",
|
|
40
|
+
};
|
|
41
|
+
mockOpaqueLoginStart.mockResolvedValue({ response: expected });
|
|
42
|
+
|
|
43
|
+
const result = await opaqueLoginStart(
|
|
44
|
+
"alice@test.com",
|
|
45
|
+
new Uint8Array([10, 20]),
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
expect(mockOpaqueLoginStart).toHaveBeenCalledWith({
|
|
49
|
+
principal: "alice@test.com",
|
|
50
|
+
credentialRequest: new Uint8Array([10, 20]),
|
|
51
|
+
});
|
|
52
|
+
expect(result).toBe(expected);
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it("propagates gRPC errors", async () => {
|
|
56
|
+
mockOpaqueLoginStart.mockRejectedValue(new Error("UNAVAILABLE"));
|
|
57
|
+
await expect(opaqueLoginStart("x", new Uint8Array())).rejects.toThrow(
|
|
58
|
+
"UNAVAILABLE",
|
|
59
|
+
);
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
describe("opaqueLoginFinish", () => {
|
|
64
|
+
it("sends principal, finalization, and serverLoginState", async () => {
|
|
65
|
+
const expected = {
|
|
66
|
+
sessionId: "sess-1",
|
|
67
|
+
accessToken: "jwt",
|
|
68
|
+
expiresIn: BigInt(3600),
|
|
69
|
+
};
|
|
70
|
+
mockOpaqueLoginFinish.mockResolvedValue({ response: expected });
|
|
71
|
+
|
|
72
|
+
const result = await opaqueLoginFinish(
|
|
73
|
+
"alice@test.com",
|
|
74
|
+
new Uint8Array([7, 8, 9]),
|
|
75
|
+
"state-123",
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
expect(mockOpaqueLoginFinish).toHaveBeenCalledWith({
|
|
79
|
+
principal: "alice@test.com",
|
|
80
|
+
credentialFinalization: new Uint8Array([7, 8, 9]),
|
|
81
|
+
serverLoginState: "state-123",
|
|
82
|
+
});
|
|
83
|
+
expect(result).toBe(expected);
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
describe("opaqueRegistrationStart", () => {
|
|
88
|
+
it("sends principal and registrationRequest", async () => {
|
|
89
|
+
const expected = {
|
|
90
|
+
registrationResponse: new Uint8Array([4, 5, 6]),
|
|
91
|
+
serverSetup: "setup-abc",
|
|
92
|
+
};
|
|
93
|
+
mockOpaqueRegistrationStart.mockResolvedValue({ response: expected });
|
|
94
|
+
|
|
95
|
+
const result = await opaqueRegistrationStart(
|
|
96
|
+
"bob@test.com",
|
|
97
|
+
new Uint8Array([11, 12]),
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
expect(mockOpaqueRegistrationStart).toHaveBeenCalledWith({
|
|
101
|
+
principal: "bob@test.com",
|
|
102
|
+
registrationRequest: new Uint8Array([11, 12]),
|
|
103
|
+
});
|
|
104
|
+
expect(result).toBe(expected);
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
describe("opaqueRegistrationFinish", () => {
|
|
109
|
+
it("sends principal, record, and serverSetup", async () => {
|
|
110
|
+
const expected = {
|
|
111
|
+
profileId: "profile-uuid",
|
|
112
|
+
credentialId: "cred-uuid",
|
|
113
|
+
serverPepper: new Uint8Array(),
|
|
114
|
+
};
|
|
115
|
+
mockOpaqueRegistrationFinish.mockResolvedValue({ response: expected });
|
|
116
|
+
|
|
117
|
+
const result = await opaqueRegistrationFinish(
|
|
118
|
+
"bob@test.com",
|
|
119
|
+
new Uint8Array([20, 21]),
|
|
120
|
+
"setup-abc",
|
|
121
|
+
);
|
|
122
|
+
|
|
123
|
+
expect(mockOpaqueRegistrationFinish).toHaveBeenCalledWith({
|
|
124
|
+
principal: "bob@test.com",
|
|
125
|
+
registrationRecord: new Uint8Array([20, 21]),
|
|
126
|
+
serverSetup: "setup-abc",
|
|
127
|
+
});
|
|
128
|
+
expect(result).toBe(expected);
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
it("propagates gRPC errors", async () => {
|
|
132
|
+
mockOpaqueRegistrationFinish.mockRejectedValue(
|
|
133
|
+
new Error("ALREADY_EXISTS"),
|
|
134
|
+
);
|
|
135
|
+
await expect(
|
|
136
|
+
opaqueRegistrationFinish("x", new Uint8Array(), "s"),
|
|
137
|
+
).rejects.toThrow("ALREADY_EXISTS");
|
|
138
|
+
});
|
|
139
|
+
});
|
|
140
|
+
});
|