@structured-id/ui-core 4.3.0 → 4.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/package.json +2 -2
- package/src/composables/index.ts +1 -8
- package/src/composables/useGrpc.test.ts +9 -125
- package/src/composables/useGrpc.ts +11 -64
- package/src/index.ts +0 -2
- package/src/profile/components/SidLoginForm.test.ts +0 -1
- package/src/profile/components/SidLoginForm.vue +1 -4
- package/src/profile/composables/useAuth.test.ts +11 -11
- package/src/profile/composables/useAuth.ts +10 -9
- package/src/profile/composables/useAuthApi.opaque.test.ts +0 -1
- package/src/types/auth.ts +0 -26
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@structured-id/ui-core",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.4.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public",
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"@protobuf-ts/grpcweb-transport": "^2.11.1",
|
|
43
43
|
"@protobuf-ts/runtime": "^2.11.1",
|
|
44
44
|
"@protobuf-ts/runtime-rpc": "^2.11.1",
|
|
45
|
-
"@structured-id/proto": "^0.
|
|
45
|
+
"@structured-id/proto": "^0.4.1",
|
|
46
46
|
"@structured-world/structured-email-address-ts": "^0.0.22",
|
|
47
47
|
"@structured-world/structured-public-domains": "0.0.x",
|
|
48
48
|
"libphonenumber-js": "^1.13.15"
|
package/src/composables/index.ts
CHANGED
|
@@ -1,11 +1,4 @@
|
|
|
1
|
-
export {
|
|
2
|
-
useGrpc,
|
|
3
|
-
initGrpc,
|
|
4
|
-
getTransport,
|
|
5
|
-
closeTransport,
|
|
6
|
-
getTransportType,
|
|
7
|
-
type TransportType,
|
|
8
|
-
} from "./useGrpc";
|
|
1
|
+
export { useGrpc, initGrpc, getTransport, closeTransport } from "./useGrpc";
|
|
9
2
|
export {
|
|
10
3
|
initAccountApi,
|
|
11
4
|
getAccountTransport,
|
|
@@ -4,28 +4,8 @@ import { describe, it, expect, vi, beforeEach } from "vitest";
|
|
|
4
4
|
// Mock modules BEFORE importing the module under test
|
|
5
5
|
// ---------------------------------------------------------------------------
|
|
6
6
|
|
|
7
|
-
const mockAdaptiveInit = vi
|
|
8
|
-
.fn<() => Promise<void>>()
|
|
9
|
-
.mockResolvedValue(undefined);
|
|
10
|
-
const mockAdaptiveClose = vi.fn();
|
|
11
|
-
const mockAdaptiveActiveTransport = vi
|
|
12
|
-
.fn<() => string>()
|
|
13
|
-
.mockReturnValue("grpc-web");
|
|
14
|
-
|
|
15
|
-
vi.mock("@structured-id/proto/transport", () => ({
|
|
16
|
-
// Constructor mocks are `function`s: they are called with `new`.
|
|
17
|
-
AdaptiveRpcTransport: vi.fn().mockImplementation(function () {
|
|
18
|
-
return {
|
|
19
|
-
init: mockAdaptiveInit,
|
|
20
|
-
close: mockAdaptiveClose,
|
|
21
|
-
get activeTransport() {
|
|
22
|
-
return mockAdaptiveActiveTransport();
|
|
23
|
-
},
|
|
24
|
-
};
|
|
25
|
-
}),
|
|
26
|
-
}));
|
|
27
|
-
|
|
28
7
|
vi.mock("@protobuf-ts/grpcweb-transport", () => ({
|
|
8
|
+
// Constructor mocks are `function`s: they are called with `new`.
|
|
29
9
|
GrpcWebFetchTransport: vi.fn().mockImplementation(function () {
|
|
30
10
|
return { type: "grpc-web-transport" };
|
|
31
11
|
}),
|
|
@@ -33,14 +13,7 @@ vi.mock("@protobuf-ts/grpcweb-transport", () => ({
|
|
|
33
13
|
|
|
34
14
|
// Import AFTER mocks
|
|
35
15
|
import { GrpcWebFetchTransport } from "@protobuf-ts/grpcweb-transport";
|
|
36
|
-
import {
|
|
37
|
-
import {
|
|
38
|
-
initGrpc,
|
|
39
|
-
getTransport,
|
|
40
|
-
closeTransport,
|
|
41
|
-
getTransportType,
|
|
42
|
-
useGrpc,
|
|
43
|
-
} from "./useGrpc";
|
|
16
|
+
import { initGrpc, getTransport, closeTransport, useGrpc } from "./useGrpc";
|
|
44
17
|
import type { GrpcConfig } from "../types/auth";
|
|
45
18
|
|
|
46
19
|
// ---------------------------------------------------------------------------
|
|
@@ -50,11 +23,12 @@ import type { GrpcConfig } from "../types/auth";
|
|
|
50
23
|
describe("useGrpc", () => {
|
|
51
24
|
beforeEach(() => {
|
|
52
25
|
vi.clearAllMocks();
|
|
53
|
-
// Reset transport state by calling close between tests
|
|
54
26
|
closeTransport();
|
|
55
27
|
});
|
|
56
28
|
|
|
57
|
-
describe("initGrpc
|
|
29
|
+
describe("initGrpc", () => {
|
|
30
|
+
// The BFF session cookie rides on every call, so credentials are always
|
|
31
|
+
// included; nothing else configures the transport.
|
|
58
32
|
it("creates GrpcWebFetchTransport with baseUrl and credentials", () => {
|
|
59
33
|
const config: GrpcConfig = { baseUrl: "https://api.sid.example.com" };
|
|
60
34
|
initGrpc(config);
|
|
@@ -63,75 +37,6 @@ describe("useGrpc", () => {
|
|
|
63
37
|
baseUrl: "https://api.sid.example.com",
|
|
64
38
|
fetchInit: { credentials: "include" },
|
|
65
39
|
});
|
|
66
|
-
expect(AdaptiveRpcTransport).not.toHaveBeenCalled();
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
it("getTransportType returns grpc-web", () => {
|
|
70
|
-
initGrpc({ baseUrl: "https://api.sid.example.com" });
|
|
71
|
-
expect(getTransportType()).toBe("grpc-web");
|
|
72
|
-
});
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
describe("initGrpc — with WebTransport URL", () => {
|
|
76
|
-
it("creates AdaptiveRpcTransport with fetchInit credentials", () => {
|
|
77
|
-
const config: GrpcConfig = {
|
|
78
|
-
baseUrl: "https://api.sid.example.com",
|
|
79
|
-
webTransportUrl: "https://wt.api.sid.example.com",
|
|
80
|
-
};
|
|
81
|
-
initGrpc(config);
|
|
82
|
-
|
|
83
|
-
expect(AdaptiveRpcTransport).toHaveBeenCalledWith(
|
|
84
|
-
expect.objectContaining({
|
|
85
|
-
grpcWebUrl: "https://api.sid.example.com",
|
|
86
|
-
webTransportUrl: "https://wt.api.sid.example.com",
|
|
87
|
-
fetchInit: { credentials: "include" },
|
|
88
|
-
}),
|
|
89
|
-
);
|
|
90
|
-
expect(GrpcWebFetchTransport).not.toHaveBeenCalled();
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
it("calls adaptive.init() non-blocking on creation", async () => {
|
|
94
|
-
initGrpc({
|
|
95
|
-
baseUrl: "https://api.sid.example.com",
|
|
96
|
-
webTransportUrl: "https://wt.api.sid.example.com",
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
// init() should be called (non-blocking fire-and-forget)
|
|
100
|
-
// Give microtasks time to run
|
|
101
|
-
await Promise.resolve();
|
|
102
|
-
expect(mockAdaptiveInit).toHaveBeenCalled();
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
it("passes all WebTransport options to AdaptiveRpcTransport", () => {
|
|
106
|
-
const onChange = vi.fn();
|
|
107
|
-
initGrpc({
|
|
108
|
-
baseUrl: "https://api.sid.example.com",
|
|
109
|
-
webTransportUrl: "https://wt.api.sid.example.com",
|
|
110
|
-
webTransportCertHash: "abcdef1234567890",
|
|
111
|
-
webTransportReconnectDelay: 3000,
|
|
112
|
-
onTransportChange: onChange,
|
|
113
|
-
});
|
|
114
|
-
|
|
115
|
-
expect(AdaptiveRpcTransport).toHaveBeenCalledWith(
|
|
116
|
-
expect.objectContaining({
|
|
117
|
-
grpcWebUrl: "https://api.sid.example.com",
|
|
118
|
-
webTransportUrl: "https://wt.api.sid.example.com",
|
|
119
|
-
webTransportCertHash: "abcdef1234567890",
|
|
120
|
-
reconnectDelay: 3000,
|
|
121
|
-
onTransportChange: onChange,
|
|
122
|
-
fetchInit: { credentials: "include" },
|
|
123
|
-
}),
|
|
124
|
-
);
|
|
125
|
-
});
|
|
126
|
-
|
|
127
|
-
it("getTransportType delegates to AdaptiveRpcTransport.activeTransport", () => {
|
|
128
|
-
mockAdaptiveActiveTransport.mockReturnValue("webtransport");
|
|
129
|
-
initGrpc({
|
|
130
|
-
baseUrl: "https://api.sid.example.com",
|
|
131
|
-
webTransportUrl: "https://wt.api.sid.example.com",
|
|
132
|
-
});
|
|
133
|
-
|
|
134
|
-
expect(getTransportType()).toBe("webtransport");
|
|
135
40
|
});
|
|
136
41
|
});
|
|
137
42
|
|
|
@@ -142,8 +47,7 @@ describe("useGrpc", () => {
|
|
|
142
47
|
|
|
143
48
|
it("returns transport after initGrpc", () => {
|
|
144
49
|
initGrpc({ baseUrl: "https://api.sid.example.com" });
|
|
145
|
-
expect(
|
|
146
|
-
expect(getTransport()).toBeDefined();
|
|
50
|
+
expect(getTransport()).toEqual({ type: "grpc-web-transport" });
|
|
147
51
|
});
|
|
148
52
|
});
|
|
149
53
|
|
|
@@ -164,36 +68,16 @@ describe("useGrpc", () => {
|
|
|
164
68
|
expect(typeof composable.getTransport).toBe("function");
|
|
165
69
|
expect(typeof composable.initGrpc).toBe("function");
|
|
166
70
|
});
|
|
167
|
-
|
|
168
|
-
it("transport.value is null after closeTransport", () => {
|
|
169
|
-
initGrpc({ baseUrl: "https://api.sid.example.com" });
|
|
170
|
-
closeTransport();
|
|
171
|
-
const { transport } = useGrpc();
|
|
172
|
-
expect(transport.value).toBeNull();
|
|
173
|
-
});
|
|
174
71
|
});
|
|
175
72
|
|
|
176
73
|
describe("closeTransport", () => {
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
baseUrl: "https://api.sid.example.com",
|
|
180
|
-
webTransportUrl: "https://wt.api.sid.example.com",
|
|
181
|
-
});
|
|
182
|
-
|
|
183
|
-
closeTransport();
|
|
184
|
-
expect(mockAdaptiveClose).toHaveBeenCalled();
|
|
185
|
-
});
|
|
186
|
-
|
|
74
|
+
// After close, the transport is gone: a later call must initialize
|
|
75
|
+
// again rather than reuse the old one.
|
|
187
76
|
it("resets transport to null (getTransport throws after close)", () => {
|
|
188
77
|
initGrpc({ baseUrl: "https://api.sid.example.com" });
|
|
189
78
|
closeTransport();
|
|
190
79
|
expect(() => getTransport()).toThrow("gRPC transport not initialized");
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
it("does not call close() on plain GrpcWebFetchTransport (no close method)", () => {
|
|
194
|
-
initGrpc({ baseUrl: "https://api.sid.example.com" });
|
|
195
|
-
// Should not throw even though GrpcWebFetchTransport has no close()
|
|
196
|
-
expect(() => closeTransport()).not.toThrow();
|
|
80
|
+
expect(useGrpc().transport.value).toBeNull();
|
|
197
81
|
});
|
|
198
82
|
});
|
|
199
83
|
});
|
|
@@ -2,67 +2,28 @@ import { GrpcWebFetchTransport } from "@protobuf-ts/grpcweb-transport";
|
|
|
2
2
|
import type { RpcTransport } from "@protobuf-ts/runtime-rpc";
|
|
3
3
|
import { ref, type Ref } from "vue";
|
|
4
4
|
import type { GrpcConfig } from "../types/auth";
|
|
5
|
-
import {
|
|
6
|
-
AdaptiveRpcTransport,
|
|
7
|
-
type TransportType,
|
|
8
|
-
} from "@structured-id/proto/transport";
|
|
9
5
|
|
|
10
|
-
/** Shared
|
|
6
|
+
/** Shared gRPC-web transport instance. */
|
|
11
7
|
let _transport: RpcTransport | null = null;
|
|
12
|
-
/** Separate reference to AdaptiveRpcTransport when active (avoids instanceof). */
|
|
13
|
-
let _adaptive: AdaptiveRpcTransport | null = null;
|
|
14
8
|
|
|
15
9
|
/**
|
|
16
|
-
* Initialize the gRPC transport. Call once at app startup.
|
|
10
|
+
* Initialize the gRPC-web transport. Call once at app startup.
|
|
17
11
|
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
* WebTransport connection is attempted asynchronously (non-blocking).
|
|
21
|
-
*
|
|
22
|
-
* Without `config.webTransportUrl`, falls back to plain gRPC-web (same as before).
|
|
23
|
-
*
|
|
24
|
-
* After BFF migration (#536i-3): `credentials: "include"` is always set
|
|
25
|
-
* so the httpOnly BFF session cookie is sent with every gRPC-web request.
|
|
12
|
+
* `credentials: "include"` is always set so the httpOnly BFF session cookie
|
|
13
|
+
* is sent with every request.
|
|
26
14
|
*
|
|
27
15
|
* @example
|
|
28
16
|
* ```ts
|
|
29
|
-
* // gRPC-web only
|
|
30
17
|
* initGrpc({ baseUrl: 'https://api.example.com' })
|
|
31
|
-
*
|
|
32
|
-
* // With WebTransport failover
|
|
33
|
-
* initGrpc({
|
|
34
|
-
* baseUrl: 'https://api.example.com',
|
|
35
|
-
* webTransportUrl: 'https://wt.api.example.com',
|
|
36
|
-
* })
|
|
37
18
|
* ```
|
|
38
19
|
*/
|
|
39
20
|
export function initGrpc(config: GrpcConfig): void {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
onTransportChange: config.onTransportChange,
|
|
47
|
-
// Always include credentials so the BFF session cookie is attached.
|
|
48
|
-
// The BFF proxy exchanges the cookie for a Bearer token server-side.
|
|
49
|
-
fetchInit: { credentials: "include" },
|
|
50
|
-
});
|
|
51
|
-
// Attempt WebTransport connection in background — non-blocking.
|
|
52
|
-
adaptive.init().catch(() => {
|
|
53
|
-
// Silently falls back to gRPC-web if WebTransport is unavailable.
|
|
54
|
-
});
|
|
55
|
-
_adaptive = adaptive;
|
|
56
|
-
_transport = adaptive;
|
|
57
|
-
} else {
|
|
58
|
-
_adaptive = null;
|
|
59
|
-
_transport = new GrpcWebFetchTransport({
|
|
60
|
-
baseUrl: config.baseUrl,
|
|
61
|
-
// Always include credentials so the BFF session cookie is attached.
|
|
62
|
-
// The BFF proxy exchanges the cookie for a Bearer token server-side.
|
|
63
|
-
fetchInit: { credentials: "include" },
|
|
64
|
-
});
|
|
65
|
-
}
|
|
21
|
+
_transport = new GrpcWebFetchTransport({
|
|
22
|
+
baseUrl: config.baseUrl,
|
|
23
|
+
// The BFF proxy exchanges the session cookie for a Bearer token
|
|
24
|
+
// server-side.
|
|
25
|
+
fetchInit: { credentials: "include" },
|
|
26
|
+
});
|
|
66
27
|
}
|
|
67
28
|
|
|
68
29
|
/**
|
|
@@ -78,24 +39,12 @@ export function getTransport(): RpcTransport {
|
|
|
78
39
|
}
|
|
79
40
|
|
|
80
41
|
/**
|
|
81
|
-
*
|
|
82
|
-
* Call during app teardown if using WebTransport.
|
|
42
|
+
* Drop the shared transport; the next use needs `initGrpc()` again.
|
|
83
43
|
*/
|
|
84
44
|
export function closeTransport(): void {
|
|
85
|
-
_adaptive?.close();
|
|
86
|
-
_adaptive = null;
|
|
87
45
|
_transport = null;
|
|
88
46
|
}
|
|
89
47
|
|
|
90
|
-
/**
|
|
91
|
-
* Get the currently active transport type.
|
|
92
|
-
* Returns "grpc-web" if AdaptiveRpcTransport is not used or WebTransport
|
|
93
|
-
* is not available.
|
|
94
|
-
*/
|
|
95
|
-
export function getTransportType(): TransportType {
|
|
96
|
-
return _adaptive?.activeTransport ?? "grpc-web";
|
|
97
|
-
}
|
|
98
|
-
|
|
99
48
|
/**
|
|
100
49
|
* Vue composable for gRPC transport.
|
|
101
50
|
*
|
|
@@ -118,5 +67,3 @@ export function useGrpc() {
|
|
|
118
67
|
initGrpc,
|
|
119
68
|
};
|
|
120
69
|
}
|
|
121
|
-
|
|
122
|
-
export type { TransportType };
|
package/src/index.ts
CHANGED
|
@@ -175,7 +175,6 @@ const props = withDefaults(
|
|
|
175
175
|
password: string,
|
|
176
176
|
onStep?: (step: number) => void,
|
|
177
177
|
) => Promise<{
|
|
178
|
-
accessToken: string;
|
|
179
178
|
expiresIn: number;
|
|
180
179
|
sessionId?: string;
|
|
181
180
|
}>;
|
|
@@ -207,9 +206,7 @@ const props = withDefaults(
|
|
|
207
206
|
);
|
|
208
207
|
|
|
209
208
|
const emit = defineEmits<{
|
|
210
|
-
success: [
|
|
211
|
-
result: { accessToken: string; expiresIn: number; sessionId?: string },
|
|
212
|
-
];
|
|
209
|
+
success: [result: { expiresIn: number; sessionId?: string }];
|
|
213
210
|
error: [error: Error];
|
|
214
211
|
"forgot-password": [];
|
|
215
212
|
}>();
|
|
@@ -125,7 +125,6 @@ describe("createAuth prewarm", () => {
|
|
|
125
125
|
});
|
|
126
126
|
api.loginFinish.mockResolvedValue({
|
|
127
127
|
sessionId: "s",
|
|
128
|
-
accessToken: "t",
|
|
129
128
|
expiresIn: 60n,
|
|
130
129
|
});
|
|
131
130
|
});
|
|
@@ -173,10 +172,13 @@ describe("createAuth register", () => {
|
|
|
173
172
|
registrationResponse: RESPONSE,
|
|
174
173
|
history: wireContext(),
|
|
175
174
|
});
|
|
176
|
-
|
|
175
|
+
// An older server's answer, still carrying a Profile identifier the
|
|
176
|
+
// current message no longer has.
|
|
177
|
+
const fromOlderServer = {
|
|
177
178
|
profileId: "profile-uuid",
|
|
178
179
|
credentialId: "cred-uuid",
|
|
179
|
-
}
|
|
180
|
+
};
|
|
181
|
+
api.regFinish.mockResolvedValue(fromOlderServer);
|
|
180
182
|
});
|
|
181
183
|
|
|
182
184
|
it("runs the operation: start, evaluate, prove, finish with the proof", async () => {
|
|
@@ -208,10 +210,9 @@ describe("createAuth register", () => {
|
|
|
208
210
|
RESPONSE,
|
|
209
211
|
);
|
|
210
212
|
expect(api.regFinish).toHaveBeenCalledWith(OPERATION, RECORD, WIRE_PROOF);
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
});
|
|
213
|
+
// Regression: the result passed the server's Profile identifier on to
|
|
214
|
+
// the application; even a server still sending one is not forwarded.
|
|
215
|
+
expect(result).toEqual({ credentialId: "cred-uuid" });
|
|
215
216
|
});
|
|
216
217
|
|
|
217
218
|
// A password the circuit cannot hold has no history request: nothing is
|
|
@@ -651,7 +652,6 @@ describe("createAuth resetPassword", () => {
|
|
|
651
652
|
api.executeReset.mockResolvedValue({ registrationResponse: RESPONSE });
|
|
652
653
|
api.completeReset.mockResolvedValue({
|
|
653
654
|
sessionId: "sess-1",
|
|
654
|
-
accessToken: "jwt",
|
|
655
655
|
expiresIn: 3600,
|
|
656
656
|
});
|
|
657
657
|
});
|
|
@@ -687,9 +687,8 @@ describe("createAuth login", () => {
|
|
|
687
687
|
});
|
|
688
688
|
api.loginFinish.mockResolvedValue({
|
|
689
689
|
sessionId: "sess-1",
|
|
690
|
-
accessToken: "jwt",
|
|
691
690
|
expiresIn: BigInt(3600),
|
|
692
|
-
}
|
|
691
|
+
});
|
|
693
692
|
});
|
|
694
693
|
|
|
695
694
|
it("signs in with the Pallas client in two round trips", async () => {
|
|
@@ -714,9 +713,10 @@ describe("createAuth login", () => {
|
|
|
714
713
|
"server-state",
|
|
715
714
|
);
|
|
716
715
|
expect(steps).toEqual([1, 2, 3]);
|
|
716
|
+
// The result carries no credential: the browser holds the session
|
|
717
|
+
// cookie the answer set.
|
|
717
718
|
expect(result).toEqual({
|
|
718
719
|
sessionId: "sess-1",
|
|
719
|
-
accessToken: "jwt",
|
|
720
720
|
expiresIn: 3600,
|
|
721
721
|
});
|
|
722
722
|
});
|
|
@@ -33,16 +33,21 @@ import {
|
|
|
33
33
|
|
|
34
34
|
// ── Types ──
|
|
35
35
|
|
|
36
|
-
/**
|
|
36
|
+
/**
|
|
37
|
+
* A sign-in's session, as the server issued it. The credential itself never
|
|
38
|
+
* reaches page code: a browser holds the session cookie the answer set.
|
|
39
|
+
*/
|
|
37
40
|
export interface LoginResult {
|
|
38
41
|
sessionId: string;
|
|
39
|
-
|
|
42
|
+
/** Seconds until the delivered credential expires. */
|
|
40
43
|
expiresIn: number;
|
|
41
44
|
}
|
|
42
45
|
|
|
43
|
-
/**
|
|
46
|
+
/**
|
|
47
|
+
* A registration's password credential. No Profile identifier: the client
|
|
48
|
+
* signs in after registering and works through its session.
|
|
49
|
+
*/
|
|
44
50
|
export interface RegisterResult {
|
|
45
|
-
profileId: string;
|
|
46
51
|
credentialId: string;
|
|
47
52
|
}
|
|
48
53
|
|
|
@@ -394,10 +399,7 @@ export function createAuth(loadClient: ZkppClientLoader) {
|
|
|
394
399
|
done.proof,
|
|
395
400
|
);
|
|
396
401
|
plan.finish();
|
|
397
|
-
return {
|
|
398
|
-
profileId: finished.profileId,
|
|
399
|
-
credentialId: finished.credentialId,
|
|
400
|
-
};
|
|
402
|
+
return { credentialId: finished.credentialId };
|
|
401
403
|
}
|
|
402
404
|
|
|
403
405
|
/**
|
|
@@ -541,7 +543,6 @@ export function createAuth(loadClient: ZkppClientLoader) {
|
|
|
541
543
|
);
|
|
542
544
|
return {
|
|
543
545
|
sessionId: finished.sessionId,
|
|
544
|
-
accessToken: finished.accessToken,
|
|
545
546
|
expiresIn: Number(finished.expiresIn),
|
|
546
547
|
};
|
|
547
548
|
}
|
|
@@ -71,7 +71,6 @@ describe("OPAQUE gRPC wrappers", () => {
|
|
|
71
71
|
it("sends principal, finalization, and serverLoginState", async () => {
|
|
72
72
|
const expected = {
|
|
73
73
|
sessionId: "sess-1",
|
|
74
|
-
accessToken: "jwt",
|
|
75
74
|
expiresIn: BigInt(3600),
|
|
76
75
|
};
|
|
77
76
|
mockOpaqueLoginFinish.mockResolvedValue({ response: expected });
|
package/src/types/auth.ts
CHANGED
|
@@ -29,30 +29,4 @@ export interface SessionInfo {
|
|
|
29
29
|
export interface GrpcConfig {
|
|
30
30
|
/** Base URL for gRPC-web transport (e.g., "https://api.example.com"). */
|
|
31
31
|
baseUrl: string;
|
|
32
|
-
/**
|
|
33
|
-
* @deprecated BFF mode always uses credentials: "include".
|
|
34
|
-
* This field is kept for API compatibility but has no effect.
|
|
35
|
-
*/
|
|
36
|
-
withCredentials?: boolean;
|
|
37
|
-
/**
|
|
38
|
-
* WebTransport server URL (e.g., "https://wt.api.example.com").
|
|
39
|
-
* When provided, AdaptiveRpcTransport is used with WebTransport as primary
|
|
40
|
-
* and gRPC-web as fallback. Omit to use gRPC-web only.
|
|
41
|
-
*/
|
|
42
|
-
webTransportUrl?: string;
|
|
43
|
-
/**
|
|
44
|
-
* SHA-256 certificate hash (hex string) for dev self-signed WebTransport certs.
|
|
45
|
-
* Only needed when connecting to servers with self-signed certificates.
|
|
46
|
-
*/
|
|
47
|
-
webTransportCertHash?: string;
|
|
48
|
-
/**
|
|
49
|
-
* Delay in milliseconds before attempting to reconnect WebTransport after failover.
|
|
50
|
-
* Defaults to 5000ms.
|
|
51
|
-
*/
|
|
52
|
-
webTransportReconnectDelay?: number;
|
|
53
|
-
/**
|
|
54
|
-
* Callback fired when the active transport changes between "webtransport" and "grpc-web".
|
|
55
|
-
* Use this to show transport status indicators in the UI.
|
|
56
|
-
*/
|
|
57
|
-
onTransportChange?: (transport: "webtransport" | "grpc-web") => void;
|
|
58
32
|
}
|