@camstack/sdk 1.1.19 → 1.1.21
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/dist/index.cjs +61 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +61 -1
- package/dist/system.d.ts +59 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -932,7 +932,8 @@ var System = class {
|
|
|
932
932
|
if (typeof result === "object" && result !== null && "token" in result) {
|
|
933
933
|
const r = result;
|
|
934
934
|
const token = r.token;
|
|
935
|
-
|
|
935
|
+
const requiresSecondFactor = r.requiresTotp === true || Array.isArray(r.secondFactors) && r.secondFactors.length > 0;
|
|
936
|
+
if (typeof token === "string" && !requiresSecondFactor) this.setToken(token);
|
|
936
937
|
}
|
|
937
938
|
return result;
|
|
938
939
|
}
|
|
@@ -954,6 +955,53 @@ var System = class {
|
|
|
954
955
|
}
|
|
955
956
|
return result;
|
|
956
957
|
}
|
|
958
|
+
/**
|
|
959
|
+
* Passkey second leg — step 1. Exchanges the login challenge token for
|
|
960
|
+
* the WebAuthn assertion options; the caller feeds `optionsJSON` to
|
|
961
|
+
* `@simplewebauthn/browser` `startAuthentication`. PUBLIC (pre-session).
|
|
962
|
+
*/
|
|
963
|
+
async loginBeginPasskey(challengeToken) {
|
|
964
|
+
return await this._trpcClient.auth.loginBeginPasskey.mutate({ challengeToken });
|
|
965
|
+
}
|
|
966
|
+
/**
|
|
967
|
+
* Passkey second leg — step 2. Submits the browser assertion; on
|
|
968
|
+
* success the server mints the real session JWT, which we set as the
|
|
969
|
+
* active token on this client.
|
|
970
|
+
*/
|
|
971
|
+
async loginVerifyPasskey(challengeToken, response) {
|
|
972
|
+
const result = await this._trpcClient.auth.loginVerifyPasskey.mutate({
|
|
973
|
+
challengeToken,
|
|
974
|
+
response
|
|
975
|
+
});
|
|
976
|
+
if (typeof result === "object" && result !== null && "token" in result) {
|
|
977
|
+
const token = result.token;
|
|
978
|
+
if (typeof token === "string") this.setToken(token);
|
|
979
|
+
}
|
|
980
|
+
return result;
|
|
981
|
+
}
|
|
982
|
+
/**
|
|
983
|
+
* Usernameless (passkey-FIRST) login — step 1. Fetches discoverable-
|
|
984
|
+
* credential assertion options (EMPTY `allowCredentials`); the caller
|
|
985
|
+
* feeds `optionsJSON` to `@simplewebauthn/browser` `startAuthentication`
|
|
986
|
+
* and the browser's own passkey picker takes over. PUBLIC (pre-session,
|
|
987
|
+
* no challenge token — the WebAuthn challenge is the whole state).
|
|
988
|
+
*/
|
|
989
|
+
async passkeyLoginBegin() {
|
|
990
|
+
return await this._trpcClient.auth.passkeyLoginBegin.mutate();
|
|
991
|
+
}
|
|
992
|
+
/**
|
|
993
|
+
* Usernameless login — step 2. Submits the browser assertion; on
|
|
994
|
+
* success the server resolves the credential's owner and mints the
|
|
995
|
+
* real session JWT, which we set as the active token on this client.
|
|
996
|
+
*/
|
|
997
|
+
async passkeyLoginFinish(response) {
|
|
998
|
+
const result = await this._trpcClient.auth.passkeyLoginFinish.mutate({ response });
|
|
999
|
+
if (typeof result === "object" && result !== null && "token" in result) {
|
|
1000
|
+
const token = result.token;
|
|
1001
|
+
if (typeof token === "string") this.setToken(token);
|
|
1002
|
+
}
|
|
1003
|
+
return result;
|
|
1004
|
+
}
|
|
957
1005
|
async logout() {
|
|
958
1006
|
await this._trpcClient.auth.logout.mutate();
|
|
959
1007
|
}
|
|
@@ -975,6 +1023,18 @@ var System = class {
|
|
|
975
1023
|
async getOwnTotpStatus() {
|
|
976
1024
|
return await this._trpcClient.auth.getOwnTotpStatus.query();
|
|
977
1025
|
}
|
|
1026
|
+
async beginOwnPasskeyRegistration() {
|
|
1027
|
+
return await this._trpcClient.auth.beginOwnPasskeyRegistration.mutate();
|
|
1028
|
+
}
|
|
1029
|
+
async finishOwnPasskeyRegistration(input) {
|
|
1030
|
+
return await this._trpcClient.auth.finishOwnPasskeyRegistration.mutate(input);
|
|
1031
|
+
}
|
|
1032
|
+
async listOwnPasskeys() {
|
|
1033
|
+
return await this._trpcClient.auth.listOwnPasskeys.query();
|
|
1034
|
+
}
|
|
1035
|
+
async removeOwnPasskey(input) {
|
|
1036
|
+
return await this._trpcClient.auth.removeOwnPasskey.mutate(input);
|
|
1037
|
+
}
|
|
978
1038
|
/** Update the auth token (e.g. after login or token refresh). */
|
|
979
1039
|
setToken(token) {
|
|
980
1040
|
this.token = token;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { System, createSystem, raceFastestEndpoint } from './system.js';
|
|
2
|
-
export type { SystemConfig, UserInfo, SystemLiveEvent, SystemLiveEventListener } from './system.js';
|
|
2
|
+
export type { SystemConfig, UserInfo, SystemLiveEvent, SystemLiveEventListener, SecondFactorKind, } from './system.js';
|
|
3
3
|
export type { DeviceInfo } from '@camstack/types';
|
|
4
4
|
export type { BackendAppRouter } from './backend-router.js';
|
|
5
5
|
export type { BackendAppRouter as AppRouter } from './backend-router.js';
|
package/dist/index.js
CHANGED
|
@@ -931,7 +931,8 @@ var System = class {
|
|
|
931
931
|
if (typeof result === "object" && result !== null && "token" in result) {
|
|
932
932
|
const r = result;
|
|
933
933
|
const token = r.token;
|
|
934
|
-
|
|
934
|
+
const requiresSecondFactor = r.requiresTotp === true || Array.isArray(r.secondFactors) && r.secondFactors.length > 0;
|
|
935
|
+
if (typeof token === "string" && !requiresSecondFactor) this.setToken(token);
|
|
935
936
|
}
|
|
936
937
|
return result;
|
|
937
938
|
}
|
|
@@ -953,6 +954,53 @@ var System = class {
|
|
|
953
954
|
}
|
|
954
955
|
return result;
|
|
955
956
|
}
|
|
957
|
+
/**
|
|
958
|
+
* Passkey second leg — step 1. Exchanges the login challenge token for
|
|
959
|
+
* the WebAuthn assertion options; the caller feeds `optionsJSON` to
|
|
960
|
+
* `@simplewebauthn/browser` `startAuthentication`. PUBLIC (pre-session).
|
|
961
|
+
*/
|
|
962
|
+
async loginBeginPasskey(challengeToken) {
|
|
963
|
+
return await this._trpcClient.auth.loginBeginPasskey.mutate({ challengeToken });
|
|
964
|
+
}
|
|
965
|
+
/**
|
|
966
|
+
* Passkey second leg — step 2. Submits the browser assertion; on
|
|
967
|
+
* success the server mints the real session JWT, which we set as the
|
|
968
|
+
* active token on this client.
|
|
969
|
+
*/
|
|
970
|
+
async loginVerifyPasskey(challengeToken, response) {
|
|
971
|
+
const result = await this._trpcClient.auth.loginVerifyPasskey.mutate({
|
|
972
|
+
challengeToken,
|
|
973
|
+
response
|
|
974
|
+
});
|
|
975
|
+
if (typeof result === "object" && result !== null && "token" in result) {
|
|
976
|
+
const token = result.token;
|
|
977
|
+
if (typeof token === "string") this.setToken(token);
|
|
978
|
+
}
|
|
979
|
+
return result;
|
|
980
|
+
}
|
|
981
|
+
/**
|
|
982
|
+
* Usernameless (passkey-FIRST) login — step 1. Fetches discoverable-
|
|
983
|
+
* credential assertion options (EMPTY `allowCredentials`); the caller
|
|
984
|
+
* feeds `optionsJSON` to `@simplewebauthn/browser` `startAuthentication`
|
|
985
|
+
* and the browser's own passkey picker takes over. PUBLIC (pre-session,
|
|
986
|
+
* no challenge token — the WebAuthn challenge is the whole state).
|
|
987
|
+
*/
|
|
988
|
+
async passkeyLoginBegin() {
|
|
989
|
+
return await this._trpcClient.auth.passkeyLoginBegin.mutate();
|
|
990
|
+
}
|
|
991
|
+
/**
|
|
992
|
+
* Usernameless login — step 2. Submits the browser assertion; on
|
|
993
|
+
* success the server resolves the credential's owner and mints the
|
|
994
|
+
* real session JWT, which we set as the active token on this client.
|
|
995
|
+
*/
|
|
996
|
+
async passkeyLoginFinish(response) {
|
|
997
|
+
const result = await this._trpcClient.auth.passkeyLoginFinish.mutate({ response });
|
|
998
|
+
if (typeof result === "object" && result !== null && "token" in result) {
|
|
999
|
+
const token = result.token;
|
|
1000
|
+
if (typeof token === "string") this.setToken(token);
|
|
1001
|
+
}
|
|
1002
|
+
return result;
|
|
1003
|
+
}
|
|
956
1004
|
async logout() {
|
|
957
1005
|
await this._trpcClient.auth.logout.mutate();
|
|
958
1006
|
}
|
|
@@ -974,6 +1022,18 @@ var System = class {
|
|
|
974
1022
|
async getOwnTotpStatus() {
|
|
975
1023
|
return await this._trpcClient.auth.getOwnTotpStatus.query();
|
|
976
1024
|
}
|
|
1025
|
+
async beginOwnPasskeyRegistration() {
|
|
1026
|
+
return await this._trpcClient.auth.beginOwnPasskeyRegistration.mutate();
|
|
1027
|
+
}
|
|
1028
|
+
async finishOwnPasskeyRegistration(input) {
|
|
1029
|
+
return await this._trpcClient.auth.finishOwnPasskeyRegistration.mutate(input);
|
|
1030
|
+
}
|
|
1031
|
+
async listOwnPasskeys() {
|
|
1032
|
+
return await this._trpcClient.auth.listOwnPasskeys.query();
|
|
1033
|
+
}
|
|
1034
|
+
async removeOwnPasskey(input) {
|
|
1035
|
+
return await this._trpcClient.auth.removeOwnPasskey.mutate(input);
|
|
1036
|
+
}
|
|
977
1037
|
/** Update the auth token (e.g. after login or token refresh). */
|
|
978
1038
|
setToken(token) {
|
|
979
1039
|
this.token = token;
|
package/dist/system.d.ts
CHANGED
|
@@ -11,9 +11,16 @@
|
|
|
11
11
|
* — a future phase will narrow the surface further.
|
|
12
12
|
*/
|
|
13
13
|
import { createWSClient, type TRPCClient } from '@trpc/client';
|
|
14
|
-
import type { DeviceProxy, DeviceInfo, DeviceQueryFilters, DeviceLifecycleListener, SystemProxy } from '@camstack/types';
|
|
14
|
+
import type { DeviceProxy, DeviceInfo, DeviceQueryFilters, DeviceLifecycleListener, SystemProxy, PasskeySummary } from '@camstack/types';
|
|
15
15
|
import type { BackendAppRouter } from './backend-router.js';
|
|
16
16
|
import type { BackendConnectionState } from './types.js';
|
|
17
|
+
/**
|
|
18
|
+
* Second-factor kinds reported by `auth.login`. Kept in the SDK (not
|
|
19
|
+
* imported from a cap) because it's a login-flow contract, not a cap
|
|
20
|
+
* surface. `totp` → the `user-management` TOTP surface; `passkey` → any
|
|
21
|
+
* `user-passkeys` cap provider.
|
|
22
|
+
*/
|
|
23
|
+
export type SecondFactorKind = 'totp' | 'passkey';
|
|
17
24
|
/**
|
|
18
25
|
* Canonical user-info shape returned by `getMe()`. Mirrors the server's
|
|
19
26
|
* `auth.me` output — kept narrow so SDK consumers don't need the full
|
|
@@ -184,6 +191,7 @@ export declare class System {
|
|
|
184
191
|
login(username: string, password: string): Promise<{
|
|
185
192
|
token: string;
|
|
186
193
|
requiresTotp?: boolean;
|
|
194
|
+
secondFactors?: readonly SecondFactorKind[];
|
|
187
195
|
}>;
|
|
188
196
|
/**
|
|
189
197
|
* Second leg of the 2FA login. The caller passes the challenge
|
|
@@ -195,6 +203,40 @@ export declare class System {
|
|
|
195
203
|
loginVerifyTotp(challengeToken: string, code: string): Promise<{
|
|
196
204
|
token: string;
|
|
197
205
|
}>;
|
|
206
|
+
/**
|
|
207
|
+
* Passkey second leg — step 1. Exchanges the login challenge token for
|
|
208
|
+
* the WebAuthn assertion options; the caller feeds `optionsJSON` to
|
|
209
|
+
* `@simplewebauthn/browser` `startAuthentication`. PUBLIC (pre-session).
|
|
210
|
+
*/
|
|
211
|
+
loginBeginPasskey(challengeToken: string): Promise<{
|
|
212
|
+
optionsJSON: Record<string, unknown>;
|
|
213
|
+
}>;
|
|
214
|
+
/**
|
|
215
|
+
* Passkey second leg — step 2. Submits the browser assertion; on
|
|
216
|
+
* success the server mints the real session JWT, which we set as the
|
|
217
|
+
* active token on this client.
|
|
218
|
+
*/
|
|
219
|
+
loginVerifyPasskey(challengeToken: string, response: Record<string, unknown>): Promise<{
|
|
220
|
+
token: string;
|
|
221
|
+
}>;
|
|
222
|
+
/**
|
|
223
|
+
* Usernameless (passkey-FIRST) login — step 1. Fetches discoverable-
|
|
224
|
+
* credential assertion options (EMPTY `allowCredentials`); the caller
|
|
225
|
+
* feeds `optionsJSON` to `@simplewebauthn/browser` `startAuthentication`
|
|
226
|
+
* and the browser's own passkey picker takes over. PUBLIC (pre-session,
|
|
227
|
+
* no challenge token — the WebAuthn challenge is the whole state).
|
|
228
|
+
*/
|
|
229
|
+
passkeyLoginBegin(): Promise<{
|
|
230
|
+
optionsJSON: Record<string, unknown>;
|
|
231
|
+
}>;
|
|
232
|
+
/**
|
|
233
|
+
* Usernameless login — step 2. Submits the browser assertion; on
|
|
234
|
+
* success the server resolves the credential's owner and mints the
|
|
235
|
+
* real session JWT, which we set as the active token on this client.
|
|
236
|
+
*/
|
|
237
|
+
passkeyLoginFinish(response: Record<string, unknown>): Promise<{
|
|
238
|
+
token: string;
|
|
239
|
+
}>;
|
|
198
240
|
logout(): Promise<void>;
|
|
199
241
|
getMe(): Promise<UserInfo>;
|
|
200
242
|
changeOwnPassword(input: {
|
|
@@ -219,6 +261,22 @@ export declare class System {
|
|
|
219
261
|
enabled: boolean;
|
|
220
262
|
confirmedAt: number | null;
|
|
221
263
|
}>;
|
|
264
|
+
beginOwnPasskeyRegistration(): Promise<{
|
|
265
|
+
optionsJSON: Record<string, unknown>;
|
|
266
|
+
}>;
|
|
267
|
+
finishOwnPasskeyRegistration(input: {
|
|
268
|
+
response: Record<string, unknown>;
|
|
269
|
+
label: string;
|
|
270
|
+
}): Promise<{
|
|
271
|
+
success: true;
|
|
272
|
+
credentialId: string;
|
|
273
|
+
}>;
|
|
274
|
+
listOwnPasskeys(): Promise<readonly PasskeySummary[]>;
|
|
275
|
+
removeOwnPasskey(input: {
|
|
276
|
+
credentialId: string;
|
|
277
|
+
}): Promise<{
|
|
278
|
+
success: true;
|
|
279
|
+
}>;
|
|
222
280
|
/** Update the auth token (e.g. after login or token refresh). */
|
|
223
281
|
setToken(token: string): void;
|
|
224
282
|
/**
|