@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 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
- if (typeof token === "string" && r.requiresTotp !== true) this.setToken(token);
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
- if (typeof token === "string" && r.requiresTotp !== true) this.setToken(token);
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
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/sdk",
3
- "version": "1.1.19",
3
+ "version": "1.1.21",
4
4
  "type": "module",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.js",