@tempoxyz/auth 0.0.0-pr-102.sha-c8a03d9 → 0.0.0-pr-104.sha-7e92695

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/Actions.js CHANGED
@@ -7,6 +7,7 @@
7
7
  import { Authentication } from 'ox/webauthn';
8
8
  import * as AccessKey from './internal/accessKey.js';
9
9
  import * as Api from './internal/api.js';
10
+ import * as Link from './internal/link.js';
10
11
  import { request } from './internal/request.js';
11
12
  export * as account from './actions/account.js';
12
13
  export * as device from './actions/device.js';
@@ -39,7 +40,12 @@ export async function authorize(auth, options = {}) {
39
40
  }));
40
41
  if (!session.user)
41
42
  return undefined;
42
- const key = await AccessKey.resolve(options.accessKey);
43
+ // A passkey sign-in's account step kept the key its assertion signed, which Tempo Auth
44
+ // authorizes with no second assertion when the passkey's account is chosen.
45
+ const kept = options.accessKey
46
+ ? undefined
47
+ : await Link.get(auth, { link: Link.account });
48
+ const key = kept ?? (await AccessKey.resolve(options.accessKey));
43
49
  const json = request(auth, {
44
50
  accessKey: key.accessKey,
45
51
  account: options.account,
@@ -49,6 +55,9 @@ export async function authorize(auth, options = {}) {
49
55
  const response = await Api.post(auth, '/v1/authorize', { json });
50
56
  if (response.status === 401)
51
57
  return undefined;
58
+ // A failed removal keeps the stale key, which the next account step replaces.
59
+ if (kept)
60
+ await Link.release(auth, { link: Link.account }).catch(() => undefined);
52
61
  const body = await Api.json(response);
53
62
  if (!('step' in body))
54
63
  return Api.authorization(body, key);
package/dist/Auth.d.ts CHANGED
@@ -48,12 +48,6 @@ export type Auth = {
48
48
  fetch?: typeof globalThis.fetch | undefined;
49
49
  /** Where Tempo Auth redirects back to. Defaults to the page's origin in a browser. */
50
50
  redirectUri?: string | undefined;
51
- /**
52
- * The URL of the API that the app's access tokens are for, which becomes their `aud` (RFC 8707).
53
- * It must be a resource indicator that Tempo Issuer registers. Without one, `aud` is the
54
- * environment's client ID.
55
- */
56
- resource?: string | undefined;
57
51
  /** The scopes the app's tokens carry. */
58
52
  scope: string;
59
53
  /**
@@ -57,13 +57,18 @@ export async function signIn(auth, options = {}) {
57
57
  json: native ? { assertion, authorize } : { assertion },
58
58
  }));
59
59
  if ('step' in body) {
60
- if (body.step.type === 'account')
60
+ if (body.step.type === 'account') {
61
+ // Choosing the passkey's account authorizes the key its assertion already signed, once
62
+ // `Actions.authorize` sends that key again.
63
+ if (!native && !options.accessKey)
64
+ await Link.keep(auth, { link: Link.account, material: key.material });
61
65
  return {
62
66
  step: {
63
67
  accounts: body.step.accounts.map(Api.tempoAccount),
64
68
  type: 'account',
65
69
  },
66
70
  };
71
+ }
67
72
  // The emailed-code sign-in that sends the link returns this key's authorization, so a key the
68
73
  // library generated waits for it in `storage`.
69
74
  if (body.step.signed && !options.accessKey)
@@ -59,8 +59,8 @@ export declare function post(auth: Auth, path: string, options: {
59
59
  json: unknown;
60
60
  }): Promise<Response>;
61
61
  /**
62
- * Calls Tempo Auth's OAuth token endpoint, adding the client, any secret, and any resource. It
63
- * forwards standard OAuth form posts to WorkOS, which binds the audience here, on every request.
62
+ * Calls Tempo Auth's OAuth token endpoint, adding the client and any secret. It forwards standard
63
+ * OAuth form posts to WorkOS.
64
64
  */
65
65
  export declare function token(auth: Auth, body: Record<string, string>): Promise<TokenResponse>;
66
66
  /** Reads the account's address, the type of its owner, which the API lists first, and its realm. */
@@ -58,8 +58,8 @@ export function post(auth, path, options) {
58
58
  });
59
59
  }
60
60
  /**
61
- * Calls Tempo Auth's OAuth token endpoint, adding the client, any secret, and any resource. It
62
- * forwards standard OAuth form posts to WorkOS, which binds the audience here, on every request.
61
+ * Calls Tempo Auth's OAuth token endpoint, adding the client and any secret. It forwards standard
62
+ * OAuth form posts to WorkOS.
63
63
  */
64
64
  export async function token(auth, body) {
65
65
  return json(await (auth.fetch ?? fetch)(new URL('/oauth2/token', auth.url), {
@@ -67,7 +67,6 @@ export async function token(auth, body) {
67
67
  ...body,
68
68
  client_id: auth.clientId,
69
69
  ...(auth.clientSecret ? { client_secret: auth.clientSecret } : {}),
70
- ...(auth.resource === undefined ? {} : { resource: auth.resource }),
71
70
  }),
72
71
  method: 'POST',
73
72
  }));
@@ -1,6 +1,8 @@
1
1
  import type { Auth } from '../Auth.ts';
2
2
  import type * as Key from '../Key.ts';
3
3
  import * as AccessKey from './accessKey.ts';
4
+ /** The `link` a key waits under after an account step, which names no link of its own. */
5
+ export declare const account = "account";
4
6
  /**
5
7
  * Keeps the key's material for `link`. Keeps nothing outside a browser without `storage`. Only the
6
8
  * link's digest is stored, since the link links the passkey for whoever sends it with a code.
@@ -1,12 +1,15 @@
1
1
  /**
2
2
  * Keeps a new key that a one-tap passkey sign-in signed, until the emailed-code sign-in that sends
3
- * its email step's `link` returns the key's authorization.
3
+ * its email step's `link`, or the `Actions.authorize` after its account step, returns the key's
4
+ * authorization.
4
5
  * @module
5
6
  */
6
7
  import { Bytes, Hash } from 'ox';
7
8
  import * as AccessKey from './accessKey.js';
8
9
  import * as Store from './store.js';
9
- /** Where the key waits in `storage`. A later email step replaces it. */
10
+ /** The `link` a key waits under after an account step, which names no link of its own. */
11
+ export const account = 'account';
12
+ /** Where the key waits in `storage`. A later email or account step replaces it. */
10
13
  const storageKey = 'tempo-auth:passkey-link';
11
14
  /**
12
15
  * Keeps the key's material for `link`. Keeps nothing outside a browser without `storage`. Only the
@@ -29,6 +29,5 @@ export declare function request(auth: Auth, options: {
29
29
  scopes: readonly Account.z_KeyAuthorization.Scope<`0x${string}`>[] | undefined;
30
30
  };
31
31
  redirect_uri: string;
32
- resource?: string;
33
32
  scope: string;
34
33
  };
@@ -29,7 +29,6 @@ export function request(auth, options) {
29
29
  scopes: permissions.scopes,
30
30
  },
31
31
  redirect_uri: auth.redirectUri ?? `${globalThis.location?.origin ?? auth.url}/`,
32
- ...(auth.resource === undefined ? {} : { resource: auth.resource }),
33
32
  scope: auth.scope,
34
33
  };
35
34
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tempoxyz/auth",
3
- "version": "0.0.0-pr-102.sha-c8a03d9",
3
+ "version": "0.0.0-pr-104.sha-7e92695",
4
4
  "description": "Signs users in to Tempo through Tempo Auth, and returns Viem access key accounts on their Tempo Accounts.",
5
5
  "type": "module",
6
6
  "exports": {