@soulcode/bexio-oauth 0.1.0 → 0.3.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.
Files changed (79) hide show
  1. package/README.md +9 -5
  2. package/dist/claims.d.ts +3 -3
  3. package/dist/claims.d.ts.map +1 -1
  4. package/dist/claims.js +5 -5
  5. package/dist/claims.js.map +1 -1
  6. package/dist/client.d.ts +4 -137
  7. package/dist/client.d.ts.map +1 -1
  8. package/dist/client.js +18 -629
  9. package/dist/client.js.map +1 -1
  10. package/dist/config.d.ts +22 -0
  11. package/dist/config.d.ts.map +1 -0
  12. package/dist/config.js +57 -0
  13. package/dist/config.js.map +1 -0
  14. package/dist/connect-flow.d.ts +15 -0
  15. package/dist/connect-flow.d.ts.map +1 -0
  16. package/dist/connect-flow.js +123 -0
  17. package/dist/connect-flow.js.map +1 -0
  18. package/dist/crypto.d.ts +2 -2
  19. package/dist/crypto.d.ts.map +1 -1
  20. package/dist/crypto.js +20 -15
  21. package/dist/crypto.js.map +1 -1
  22. package/dist/errors.d.ts +1 -1
  23. package/dist/errors.d.ts.map +1 -1
  24. package/dist/external-tokens.d.ts +8 -0
  25. package/dist/external-tokens.d.ts.map +1 -0
  26. package/dist/external-tokens.js +73 -0
  27. package/dist/external-tokens.js.map +1 -0
  28. package/dist/flow-cookie.d.ts +23 -0
  29. package/dist/flow-cookie.d.ts.map +1 -0
  30. package/dist/flow-cookie.js +44 -0
  31. package/dist/flow-cookie.js.map +1 -0
  32. package/dist/grants.d.ts +45 -0
  33. package/dist/grants.d.ts.map +1 -0
  34. package/dist/grants.js +143 -0
  35. package/dist/grants.js.map +1 -0
  36. package/dist/idle-sweep.d.ts +11 -0
  37. package/dist/idle-sweep.d.ts.map +1 -0
  38. package/dist/idle-sweep.js +70 -0
  39. package/dist/idle-sweep.js.map +1 -0
  40. package/dist/index.d.ts +3 -2
  41. package/dist/index.d.ts.map +1 -1
  42. package/dist/index.js +1 -1
  43. package/dist/index.js.map +1 -1
  44. package/dist/migrations.generated.d.ts +3 -0
  45. package/dist/migrations.generated.d.ts.map +1 -0
  46. package/dist/migrations.generated.js +56 -0
  47. package/dist/migrations.generated.js.map +1 -0
  48. package/dist/oidc.d.ts +30 -0
  49. package/dist/oidc.d.ts.map +1 -0
  50. package/dist/oidc.js +67 -0
  51. package/dist/oidc.js.map +1 -0
  52. package/dist/refresh.d.ts +30 -0
  53. package/dist/refresh.d.ts.map +1 -0
  54. package/dist/refresh.js +147 -0
  55. package/dist/refresh.js.map +1 -0
  56. package/dist/return-to.d.ts +8 -0
  57. package/dist/return-to.d.ts.map +1 -0
  58. package/dist/return-to.js +31 -0
  59. package/dist/return-to.js.map +1 -0
  60. package/dist/sql.d.ts +6 -1
  61. package/dist/sql.d.ts.map +1 -1
  62. package/dist/sql.js +8 -12
  63. package/dist/sql.js.map +1 -1
  64. package/dist/store/memory.d.ts.map +1 -1
  65. package/dist/store/memory.js +82 -46
  66. package/dist/store/memory.js.map +1 -1
  67. package/dist/store/postgres.d.ts +4 -4
  68. package/dist/store/postgres.d.ts.map +1 -1
  69. package/dist/store/postgres.js +137 -59
  70. package/dist/store/postgres.js.map +1 -1
  71. package/dist/store/types.d.ts +61 -21
  72. package/dist/store/types.d.ts.map +1 -1
  73. package/dist/types.d.ts +164 -0
  74. package/dist/types.d.ts.map +1 -0
  75. package/dist/types.js +2 -0
  76. package/dist/types.js.map +1 -0
  77. package/package.json +3 -1
  78. package/sql/0001_bexio_oauth.sql +48 -0
  79. package/sql/0001_bexio_grants.sql +0 -32
@@ -1,16 +1,53 @@
1
- const COLUMNS = `id, owner_id, bexio_company_id, bexio_user_id, bexio_company_user_id,
1
+ import { BexioOAuthError } from "../errors.js";
2
+ // `id` columns are uuids: any other value matches no row, and would make
3
+ // Postgres reject the cast instead of returning nothing.
4
+ const UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
5
+ const CONNECTION_COLUMNS = `id, bexio_company_id, bexio_user_id, bexio_company_user_id,
2
6
  company_name, user_name, user_email, role, status, access_token, refresh_token,
3
7
  access_expires_at, refresh_expires_at, scope, refresh_locked_until,
4
- last_refreshed_at, created_at, updated_at`;
8
+ authorized_at, last_refreshed_at, created_at, updated_at`;
9
+ /** Connection columns qualified with `c.`, for joins. */
10
+ const C_COLUMNS = CONNECTION_COLUMNS.split(",")
11
+ .map((column) => `c.${column.trim()}`)
12
+ .join(", ");
13
+ /** A grant joined with its connection (`c`) and the grant (`g`). */
14
+ const GRANT_COLUMNS = `g.id AS grant_id, g.owner_id, g.created_at AS grant_created_at, ${C_COLUMNS}`;
15
+ /**
16
+ * The connection's columns an upsert sets, and the value each takes. They
17
+ * change only for an authorization at least as new as the stored one: Bexio
18
+ * has invalidated the older chain, so a slow connect that authorized earlier
19
+ * must not overwrite a later one. The grant is linked either way.
20
+ */
21
+ const UPSERT_VALUES = [
22
+ ["bexio_company_user_id", "EXCLUDED.bexio_company_user_id"],
23
+ ["company_name", "EXCLUDED.company_name"],
24
+ ["user_name", "EXCLUDED.user_name"],
25
+ ["user_email", "EXCLUDED.user_email"],
26
+ ["role", "EXCLUDED.role"],
27
+ ["status", "'active'"],
28
+ ["access_token", "EXCLUDED.access_token"],
29
+ ["refresh_token", "EXCLUDED.refresh_token"],
30
+ ["access_expires_at", "EXCLUDED.access_expires_at"],
31
+ ["refresh_expires_at", "EXCLUDED.refresh_expires_at"],
32
+ ["scope", "EXCLUDED.scope"],
33
+ ["refresh_locked_until", "NULL"],
34
+ ["refresh_lock_token", "NULL"],
35
+ ["authorized_at", "EXCLUDED.authorized_at"],
36
+ ["last_refreshed_at", "EXCLUDED.last_refreshed_at"],
37
+ ["updated_at", "EXCLUDED.updated_at"],
38
+ ];
39
+ const NEWER_AUTHORIZATION_WINS = UPSERT_VALUES.map(([column, value]) => `${column} = CASE WHEN EXCLUDED.authorized_at >= bexio_connections.authorized_at
40
+ THEN ${value} ELSE bexio_connections.${column} END`).join(",\n ");
41
+ /** SQLSTATE for a foreign key violation. */
42
+ const FOREIGN_KEY_VIOLATION = "23503";
5
43
  function date(value) {
6
44
  if (value === null)
7
45
  return null;
8
46
  return value instanceof Date ? value : new Date(value);
9
47
  }
10
- function toRecord(row) {
48
+ function toConnection(row) {
11
49
  return {
12
50
  id: row.id,
13
- ownerId: row.owner_id,
14
51
  companyId: row.bexio_company_id,
15
52
  userId: row.bexio_user_id,
16
53
  companyUserId: row.bexio_company_user_id === null
@@ -27,49 +64,49 @@ function toRecord(row) {
27
64
  refreshExpiresAt: date(row.refresh_expires_at),
28
65
  scope: row.scope,
29
66
  refreshLockedUntil: date(row.refresh_locked_until),
67
+ authorizedAt: date(row.authorized_at),
30
68
  lastRefreshedAt: date(row.last_refreshed_at),
31
69
  createdAt: date(row.created_at),
32
70
  updatedAt: date(row.updated_at),
33
71
  };
34
72
  }
73
+ function toGrant(row) {
74
+ return {
75
+ id: row.grant_id,
76
+ ownerId: row.owner_id,
77
+ createdAt: date(row.grant_created_at),
78
+ connection: toConnection(row),
79
+ };
80
+ }
35
81
  /**
36
- * Grant store on the `bexio_grants` table (create it with
37
- * `npx @soulcode/bexio-oauth sql`). Every operation is a single statement,
38
- * so it works through transaction-mode poolers and HTTP drivers.
82
+ * Store on the `bexio_connections` and `bexio_grants` tables (create them
83
+ * with `npx @soulcode/bexio-oauth sql`). Every operation is a single
84
+ * statement, so it works through transaction-mode poolers and HTTP drivers.
39
85
  */
40
86
  export function postgresStore(sql) {
41
- const one = async (text, params) => {
87
+ const connection = async (text, params) => {
42
88
  const { rows } = await sql.query(text, params);
43
- return rows[0] ? toRecord(rows[0]) : null;
44
- };
45
- const many = async (text, params) => {
46
- const { rows } = await sql.query(text, params);
47
- return rows.map(toRecord);
89
+ return rows[0] ? toConnection(rows[0]) : null;
48
90
  };
49
91
  return {
50
92
  async upsertGrant(g) {
51
- const row = await one(`INSERT INTO bexio_grants (owner_id, bexio_company_id, bexio_user_id,
52
- bexio_company_user_id, company_name, user_name, user_email, role, status,
53
- access_token, refresh_token, access_expires_at, refresh_expires_at, scope,
54
- refresh_locked_until, last_refreshed_at, created_at, updated_at)
55
- VALUES ($1, $2, $3, $4, $5, $6, $7, $8, 'active', $9, $10, $11, $12, $13, NULL, $14, $14, $14)
56
- ON CONFLICT (owner_id, bexio_company_id, bexio_user_id) DO UPDATE SET
57
- bexio_company_user_id = EXCLUDED.bexio_company_user_id,
58
- company_name = EXCLUDED.company_name,
59
- user_name = EXCLUDED.user_name,
60
- user_email = EXCLUDED.user_email,
61
- role = EXCLUDED.role,
62
- status = 'active',
63
- access_token = EXCLUDED.access_token,
64
- refresh_token = EXCLUDED.refresh_token,
65
- access_expires_at = EXCLUDED.access_expires_at,
66
- refresh_expires_at = EXCLUDED.refresh_expires_at,
67
- scope = EXCLUDED.scope,
68
- refresh_locked_until = NULL,
69
- refresh_lock_token = NULL,
70
- last_refreshed_at = EXCLUDED.last_refreshed_at,
71
- updated_at = EXCLUDED.updated_at
72
- RETURNING ${COLUMNS}`, [
93
+ const { rows } = await sql.query(`WITH connection AS (
94
+ INSERT INTO bexio_connections (bexio_company_id, bexio_user_id,
95
+ bexio_company_user_id, company_name, user_name, user_email, role, status,
96
+ access_token, refresh_token, access_expires_at, refresh_expires_at, scope,
97
+ refresh_locked_until, refresh_lock_token, authorized_at, last_refreshed_at,
98
+ created_at, updated_at)
99
+ VALUES ($2, $3, $4, $5, $6, $7, $8, 'active', $9, $10, $11, $12, $13, NULL, NULL, $15, $14, $14, $14)
100
+ ON CONFLICT (bexio_company_id, bexio_user_id) DO UPDATE SET
101
+ ${NEWER_AUTHORIZATION_WINS}
102
+ RETURNING ${CONNECTION_COLUMNS}
103
+ ), g AS (
104
+ INSERT INTO bexio_grants (owner_id, connection_id, created_at)
105
+ SELECT $1, id, $14 FROM connection
106
+ ON CONFLICT (owner_id, connection_id) DO UPDATE SET owner_id = EXCLUDED.owner_id
107
+ RETURNING id, owner_id, created_at
108
+ )
109
+ SELECT ${GRANT_COLUMNS} FROM g, connection c`, [
73
110
  g.ownerId,
74
111
  g.companyId,
75
112
  g.userId,
@@ -84,23 +121,64 @@ export function postgresStore(sql) {
84
121
  g.refreshExpiresAt,
85
122
  g.scope,
86
123
  g.now,
124
+ g.authorizedAt,
87
125
  ]);
88
- if (!row)
89
- throw new Error("upsert returned no row");
90
- return row;
126
+ if (!rows[0]) {
127
+ throw new BexioOAuthError("invalid_config", "SqlClient returned no row for INSERT … RETURNING; check the driver wrapper");
128
+ }
129
+ return toGrant(rows[0]);
91
130
  },
92
131
  async findGrants({ ownerId, companyId, grantId }) {
93
- return many(`SELECT ${COLUMNS} FROM bexio_grants
94
- WHERE owner_id = $1
95
- AND ($2::text IS NULL OR bexio_company_id = $2)
96
- AND ($3::uuid IS NULL OR id = $3::uuid)
97
- ORDER BY created_at, id`, [ownerId, companyId ?? null, grantId ?? null]);
132
+ if (grantId !== undefined && !UUID.test(grantId))
133
+ return [];
134
+ const { rows } = await sql.query(`SELECT ${GRANT_COLUMNS}
135
+ FROM bexio_grants g JOIN bexio_connections c ON c.id = g.connection_id
136
+ WHERE g.owner_id = $1
137
+ AND ($2::text IS NULL OR c.bexio_company_id = $2)
138
+ AND ($3::uuid IS NULL OR g.id = $3::uuid)
139
+ ORDER BY g.created_at, g.id`, [ownerId, companyId ?? null, grantId ?? null]);
140
+ return rows.map(toGrant);
141
+ },
142
+ async deleteGrant(id) {
143
+ if (!UUID.test(id))
144
+ return;
145
+ await sql.query(`DELETE FROM bexio_grants WHERE id = $1`, [id]);
98
146
  },
99
- async getGrant(id) {
100
- return one(`SELECT ${COLUMNS} FROM bexio_grants WHERE id = $1`, [id]);
147
+ async getConnection(id) {
148
+ if (!UUID.test(id))
149
+ return null;
150
+ return connection(`SELECT ${CONNECTION_COLUMNS} FROM bexio_connections WHERE id = $1`, [id]);
151
+ },
152
+ // NOT EXISTS reads the statement's snapshot, so it can miss a grant that
153
+ // a concurrent upsertGrant commits meanwhile. The foreign key catches
154
+ // that case: it checks against committed data and fails the delete.
155
+ async deleteUnusedConnection(id) {
156
+ if (!UUID.test(id))
157
+ return null;
158
+ try {
159
+ const { rows } = await sql.query(`DELETE FROM bexio_connections c
160
+ WHERE c.id = $1
161
+ AND NOT EXISTS (SELECT 1 FROM bexio_grants g WHERE g.connection_id = c.id)
162
+ RETURNING ${C_COLUMNS}, EXISTS (
163
+ SELECT 1 FROM bexio_connections o
164
+ WHERE o.bexio_user_id = c.bexio_user_id AND o.id <> c.id
165
+ ) AS user_has_other_connections`, [id]);
166
+ const row = rows[0];
167
+ return row
168
+ ? {
169
+ connection: toConnection(row),
170
+ userHasOtherConnections: row.user_has_other_connections,
171
+ }
172
+ : null;
173
+ }
174
+ catch (error) {
175
+ if (error.code === FOREIGN_KEY_VIOLATION)
176
+ return null;
177
+ throw error;
178
+ }
101
179
  },
102
180
  async acquireRefreshLock({ id, now, lockUntil, lockToken, accessExpiresBefore, refreshedBefore, }) {
103
- return one(`UPDATE bexio_grants SET refresh_locked_until = $3, refresh_lock_token = $6
181
+ return connection(`UPDATE bexio_connections SET refresh_locked_until = $3, refresh_lock_token = $6
104
182
  WHERE id = $1
105
183
  AND status = 'active'
106
184
  AND (refresh_locked_until IS NULL OR refresh_locked_until <= $2)
@@ -108,7 +186,7 @@ export function postgresStore(sql) {
108
186
  ($4::timestamptz IS NOT NULL AND (access_expires_at IS NULL OR access_expires_at <= $4))
109
187
  OR ($5::timestamptz IS NOT NULL AND last_refreshed_at < $5)
110
188
  )
111
- RETURNING ${COLUMNS}`, [
189
+ RETURNING ${CONNECTION_COLUMNS}`, [
112
190
  id,
113
191
  now,
114
192
  lockUntil,
@@ -120,7 +198,7 @@ export function postgresStore(sql) {
120
198
  // Holder writes are fenced by refresh_lock_token: a holder whose lock
121
199
  // expired or was cleared by a reconnect matches no row and changes nothing.
122
200
  async saveRefreshed(id, lockToken, r) {
123
- return one(`UPDATE bexio_grants SET
201
+ return connection(`UPDATE bexio_connections SET
124
202
  access_token = $2,
125
203
  refresh_token = COALESCE($3, refresh_token),
126
204
  access_expires_at = $4,
@@ -133,7 +211,7 @@ export function postgresStore(sql) {
133
211
  last_refreshed_at = $8,
134
212
  updated_at = $8
135
213
  WHERE id = $1 AND refresh_lock_token = $9
136
- RETURNING ${COLUMNS}`, [
214
+ RETURNING ${CONNECTION_COLUMNS}`, [
137
215
  id,
138
216
  r.accessToken,
139
217
  r.refreshToken,
@@ -146,22 +224,22 @@ export function postgresStore(sql) {
146
224
  ]);
147
225
  },
148
226
  async markReauthRequired(id, lockToken, now) {
149
- await sql.query(`UPDATE bexio_grants SET status = 'reauth_required',
227
+ return connection(`UPDATE bexio_connections SET status = 'reauth_required',
150
228
  refresh_locked_until = NULL, refresh_lock_token = NULL, updated_at = $2
151
- WHERE id = $1 AND refresh_lock_token = $3`, [id, now, lockToken]);
229
+ WHERE id = $1 AND refresh_lock_token = $3
230
+ RETURNING ${CONNECTION_COLUMNS}`, [id, now, lockToken]);
152
231
  },
153
232
  async releaseRefreshLock(id, lockToken) {
154
- await sql.query(`UPDATE bexio_grants SET refresh_locked_until = NULL, refresh_lock_token = NULL
233
+ await sql.query(`UPDATE bexio_connections SET refresh_locked_until = NULL, refresh_lock_token = NULL
155
234
  WHERE id = $1 AND refresh_lock_token = $2`, [id, lockToken]);
156
235
  },
157
- async deleteGrant(id) {
158
- await sql.query(`DELETE FROM bexio_grants WHERE id = $1`, [id]);
159
- },
160
- async listIdleGrants({ refreshedBefore, limit }) {
161
- return many(`SELECT ${COLUMNS} FROM bexio_grants
162
- WHERE status = 'active' AND last_refreshed_at < $1
163
- ORDER BY last_refreshed_at
236
+ async listIdleConnections({ refreshedBefore, limit }) {
237
+ const { rows } = await sql.query(`SELECT ${CONNECTION_COLUMNS} FROM bexio_connections c
238
+ WHERE c.status = 'active' AND c.last_refreshed_at < $1
239
+ AND EXISTS (SELECT 1 FROM bexio_grants g WHERE g.connection_id = c.id)
240
+ ORDER BY c.last_refreshed_at
164
241
  LIMIT $2`, [refreshedBefore, limit]);
242
+ return rows.map(toConnection);
165
243
  },
166
244
  };
167
245
  }
@@ -1 +1 @@
1
- {"version":3,"file":"postgres.js","sourceRoot":"","sources":["../../src/store/postgres.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"postgres.js","sourceRoot":"","sources":["../../src/store/postgres.ts"],"names":[],"mappings":"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"}
@@ -1,9 +1,12 @@
1
1
  import type { Role } from "../permissions.js";
2
2
  export type GrantStatus = "active" | "reauth_required";
3
- /** A stored grant. Token fields hold JWE ciphertext, never plaintext. */
4
- export interface GrantRecord {
3
+ /**
4
+ * A stored connection: one Bexio identity (company, user) and the tokens of
5
+ * its refresh token chain, shared by every owner that connected it. Token
6
+ * fields hold JWE ciphertext, never plaintext.
7
+ */
8
+ export interface ConnectionRecord {
5
9
  id: string;
6
- ownerId: string;
7
10
  companyId: string;
8
11
  userId: string;
9
12
  companyUserId: number | null;
@@ -18,11 +21,26 @@ export interface GrantRecord {
18
21
  refreshExpiresAt: Date | null;
19
22
  scope: string | null;
20
23
  refreshLockedUntil: Date | null;
24
+ /** When Bexio issued the authorization the tokens belong to. */
25
+ authorizedAt: Date;
21
26
  lastRefreshedAt: Date;
22
27
  createdAt: Date;
23
28
  updatedAt: Date;
24
29
  }
25
- /** Insert, or overwrite the tokens of, the grant for (owner, company, user). */
30
+ /** A stored grant: one owner's access to a connection. */
31
+ export interface GrantRecord {
32
+ id: string;
33
+ ownerId: string;
34
+ createdAt: Date;
35
+ connection: ConnectionRecord;
36
+ }
37
+ /**
38
+ * Upsert of the connection for (company, user) and of the grant for (owner,
39
+ * that connection). The grant is always linked. The connection takes the new
40
+ * tokens (status `active`, lock cleared) unless it already holds a newer
41
+ * authorization: Bexio invalidates older chains, so a slow connect that
42
+ * authorized earlier must not overwrite a later one.
43
+ */
26
44
  export interface GrantUpsert {
27
45
  ownerId: string;
28
46
  companyId: string;
@@ -37,9 +55,11 @@ export interface GrantUpsert {
37
55
  accessExpiresAt: Date | null;
38
56
  refreshExpiresAt: Date | null;
39
57
  scope: string | null;
58
+ /** When Bexio issued this authorization (the access token's `iat`). */
59
+ authorizedAt: Date;
40
60
  now: Date;
41
61
  }
42
- export interface GrantRefresh {
62
+ export interface ConnectionRefresh {
43
63
  accessToken: string;
44
64
  /** `null` keeps the stored refresh token (the IdP didn't rotate it). */
45
65
  refreshToken: string | null;
@@ -53,6 +73,7 @@ export interface GrantRefresh {
53
73
  now: Date;
54
74
  }
55
75
  export interface LockRequest {
76
+ /** The connection to lock. */
56
77
  id: string;
57
78
  now: Date;
58
79
  lockUntil: Date;
@@ -64,42 +85,61 @@ export interface LockRequest {
64
85
  lockToken: string;
65
86
  /** Lock only if the access token expires before this instant (lazy refresh)… */
66
87
  accessExpiresBefore?: Date;
67
- /** …or only if the grant was last refreshed before this instant (idle sweep). */
88
+ /** …or only if the connection was last refreshed before this instant (idle sweep). */
68
89
  refreshedBefore?: Date;
69
90
  }
70
91
  /**
71
- * Persistence for grants. Every method must be atomic on its own: the
72
- * library never needs multi-statement transactions.
92
+ * Persistence for connections and grants. Every method must be atomic on its
93
+ * own: the library never needs multi-statement transactions.
73
94
  */
74
95
  export interface GrantStore {
96
+ /** See `GrantUpsert`. Returns the grant with its connection. */
75
97
  upsertGrant(input: GrantUpsert): Promise<GrantRecord>;
98
+ /** The owner's grants with their connections, oldest first. */
76
99
  findGrants(query: {
77
100
  ownerId: string;
78
101
  companyId?: string;
79
102
  grantId?: string;
80
103
  }): Promise<GrantRecord[]>;
81
- getGrant(id: string): Promise<GrantRecord | null>;
104
+ /** Deletes one grant; its connection stays. */
105
+ deleteGrant(id: string): Promise<void>;
106
+ getConnection(id: string): Promise<ConnectionRecord | null>;
82
107
  /**
83
- * Takes the refresh lock if the grant is active, not locked (or the lock
84
- * expired), and still matches the `accessExpiresBefore` / `refreshedBefore`
85
- * condition. Returns the locked row, or `null` if someone else holds the
86
- * lock or the grant no longer needs a refresh.
108
+ * Deletes the connection if no grant references it any more, and returns
109
+ * the deleted row, plus whether the same Bexio user still has a connection
110
+ * (for another company). Returns `null` (and changes nothing) while a grant
111
+ * still references it, including one added concurrently.
87
112
  */
88
- acquireRefreshLock(request: LockRequest): Promise<GrantRecord | null>;
113
+ deleteUnusedConnection(id: string): Promise<{
114
+ connection: ConnectionRecord;
115
+ userHasOtherConnections: boolean;
116
+ } | null>;
117
+ /**
118
+ * Takes the refresh lock if the connection is active, not locked (or the
119
+ * lock expired), and still matches the `accessExpiresBefore` /
120
+ * `refreshedBefore` condition. Returns the locked row, or `null` if someone
121
+ * else holds the lock or the connection no longer needs a refresh.
122
+ */
123
+ acquireRefreshLock(request: LockRequest): Promise<ConnectionRecord | null>;
89
124
  /**
90
125
  * Stores refreshed tokens, sets `lastRefreshedAt`, and releases the lock.
91
126
  * Returns `null` (and changes nothing) unless `lockToken` still holds it.
92
127
  */
93
- saveRefreshed(id: string, lockToken: string, refresh: GrantRefresh): Promise<GrantRecord | null>;
94
- /** Sets `status = reauth_required` and releases the lock, if `lockToken` holds it. */
95
- markReauthRequired(id: string, lockToken: string, now: Date): Promise<void>;
128
+ saveRefreshed(id: string, lockToken: string, refresh: ConnectionRefresh): Promise<ConnectionRecord | null>;
129
+ /**
130
+ * Sets `status = reauth_required` and releases the lock. Returns `null`
131
+ * (and changes nothing) unless `lockToken` still holds it.
132
+ */
133
+ markReauthRequired(id: string, lockToken: string, now: Date): Promise<ConnectionRecord | null>;
96
134
  /** Releases the lock, if `lockToken` holds it. */
97
135
  releaseRefreshLock(id: string, lockToken: string): Promise<void>;
98
- deleteGrant(id: string): Promise<void>;
99
- /** Active grants last refreshed before `refreshedBefore`, oldest first. */
100
- listIdleGrants(query: {
136
+ /**
137
+ * Active connections that at least one grant references, last refreshed
138
+ * before `refreshedBefore`, oldest first.
139
+ */
140
+ listIdleConnections(query: {
101
141
  refreshedBefore: Date;
102
142
  limit: number;
103
- }): Promise<GrantRecord[]>;
143
+ }): Promise<ConnectionRecord[]>;
104
144
  }
105
145
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/store/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/store/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,164 @@
1
+ import type { Keyring } from "./crypto.js";
2
+ import type { Duration } from "./duration.js";
3
+ import type { Role } from "./permissions.js";
4
+ import type { GrantStatus, GrantStore } from "./store/types.js";
5
+ export interface BexioOAuthConfig {
6
+ /** From your Bexio OAuth app. */
7
+ clientId: string;
8
+ clientSecret: string;
9
+ /** Must exactly match a redirect URI registered at Bexio. */
10
+ redirectUri: string;
11
+ /** Bexio API scopes your app needs; `BASE_SCOPES` are always added. */
12
+ scopes?: string[];
13
+ /** Encryption keyring (see `generateKey`). */
14
+ keys: Keyring;
15
+ store: GrantStore;
16
+ /** Defaults to Bexio's production issuer. Override only to point at a mock. */
17
+ issuer?: string;
18
+ /** Defaults to `https://api.bexio.com`. Override only to point at a mock. */
19
+ apiBaseUrl?: string;
20
+ /** How long one refresh may hold a connection's lock. Default `"30s"`. */
21
+ refreshLockTtl?: Duration;
22
+ /** Where `callback` redirects when the flow cookie is gone. Default `"/"`. */
23
+ defaultReturnTo?: string;
24
+ /** Custom `fetch` for every outgoing request (tests, proxies). */
25
+ fetch?: typeof fetch;
26
+ /** Clock override for tests. */
27
+ clock?: () => Date;
28
+ }
29
+ /**
30
+ * A grant as the app sees it: one owner's access to a connection, without
31
+ * token material. Grants of the same Bexio identity share one connection,
32
+ * so they share its tokens, role and status.
33
+ */
34
+ export interface Grant {
35
+ id: string;
36
+ ownerId: string;
37
+ /** Shared by every grant of the same Bexio company and user. */
38
+ connectionId: string;
39
+ companyId: string;
40
+ companyName: string | null;
41
+ userId: string;
42
+ userName: string | null;
43
+ userEmail: string | null;
44
+ companyUserId: number | null;
45
+ role: Role;
46
+ status: GrantStatus;
47
+ scope: string | null;
48
+ accessExpiresAt: Date | null;
49
+ lastRefreshedAt: Date;
50
+ /** When this owner connected. */
51
+ createdAt: Date;
52
+ /** When the connection last changed. */
53
+ updatedAt: Date;
54
+ }
55
+ /** Identifies one grant of an owner. */
56
+ export interface GrantSelector {
57
+ ownerId: string;
58
+ companyId?: string;
59
+ grantId?: string;
60
+ }
61
+ export interface AccessToken {
62
+ accessToken: string;
63
+ expiresAt: Date | null;
64
+ grant: Grant;
65
+ }
66
+ /** Tokens obtained by your auth framework, for `saveGrant`. */
67
+ export interface ExternalTokens {
68
+ accessToken: string;
69
+ refreshToken?: string | null;
70
+ idToken?: string | null;
71
+ /** Access-token expiry; defaults to the access token's `exp` claim. */
72
+ expiresAt?: Date | null;
73
+ scope?: string | null;
74
+ }
75
+ /** Counts connections, not grants: owners of one Bexio identity share one. */
76
+ export interface RefreshIdleResult {
77
+ refreshed: number;
78
+ /** Idle connections another process was refreshing at the same time. */
79
+ skipped: number;
80
+ reauthRequired: number;
81
+ failed: number;
82
+ /**
83
+ * Idle connections not attempted because `timeBudget` ran out (0 when every
84
+ * idle connection of this run was attempted). The next run picks them up
85
+ * first.
86
+ */
87
+ remaining: number;
88
+ }
89
+ /**
90
+ * How the callback checks the owner. Either the `ownerId` your app derives
91
+ * from the signed-in session (must equal the one passed to `start`), or
92
+ * `authorizeOwner`, which receives the owner recorded at `start` and returns
93
+ * whether the signed-in user may connect Bexio for it. Use the latter when
94
+ * one callback URL serves many owners (e.g. workspaces).
95
+ */
96
+ export type CallbackOptions = {
97
+ ownerId: string;
98
+ } | {
99
+ authorizeOwner: (ownerId: string) => boolean | Promise<boolean>;
100
+ };
101
+ export interface CallbackResult {
102
+ grant: Grant;
103
+ returnTo: string;
104
+ /** Contains the `Set-Cookie` that deletes the flow cookie; copy it onto your response. */
105
+ headers: Headers;
106
+ }
107
+ /** The client returned by `createBexioOAuth`. */
108
+ export interface BexioOAuth {
109
+ /**
110
+ * Starts the Connect flow: returns a redirect to Bexio that sets the
111
+ * encrypted flow cookie. Derive `ownerId` from your authenticated session.
112
+ * `returnTo` must be a relative path (default: `defaultReturnTo`).
113
+ */
114
+ start(options: {
115
+ ownerId: string;
116
+ returnTo?: string;
117
+ }): Promise<Response>;
118
+ /**
119
+ * Handles the redirect back from Bexio, saves the grant, and redirects to
120
+ * `returnTo` (or `returnTo?bexio_error=<code>` on failure). Only
121
+ * `invalid_config` and non-library errors are thrown.
122
+ */
123
+ callback(request: Request, options: CallbackOptions): Promise<Response>;
124
+ /**
125
+ * Handles the redirect back from Bexio and saves the grant. Throws a
126
+ * `BexioOAuthError` on failure; use `callback` for a ready-made redirect.
127
+ */
128
+ handleCallback(request: Request, options: CallbackOptions): Promise<CallbackResult>;
129
+ /**
130
+ * Saves tokens obtained by your auth framework ("Sign in with Bexio").
131
+ * Verifies the tokens' signatures against Bexio's keys first.
132
+ */
133
+ saveGrant(input: {
134
+ ownerId: string;
135
+ tokens: ExternalTokens;
136
+ }): Promise<Grant>;
137
+ /**
138
+ * A valid access token for the owner's grant, refreshed when needed.
139
+ * Safe to call from background jobs and from many instances at once.
140
+ */
141
+ getAccessToken(selector: GrantSelector): Promise<AccessToken>;
142
+ /** The owner's grants, without token material. */
143
+ listGrants(query: {
144
+ ownerId: string;
145
+ }): Promise<Grant[]>;
146
+ /**
147
+ * Deletes the owner's grant. When it was the last grant of its connection,
148
+ * also deletes the connection and revokes its refresh token at Bexio (best
149
+ * effort). Other owners of the same Bexio identity keep working.
150
+ */
151
+ disconnect(selector: GrantSelector): Promise<void>;
152
+ /**
153
+ * Refreshes active connections not refreshed for `idleFor`, so Bexio
154
+ * doesn't end their offline sessions. Run it on a schedule. `limit`
155
+ * (default 100) caps the connections one run looks at; `timeBudget` stops
156
+ * the run before the next connection once that much time has passed.
157
+ */
158
+ refreshIdle(options: {
159
+ idleFor: Duration;
160
+ limit?: number;
161
+ timeBudget?: Duration;
162
+ }): Promise<RefreshIdleResult>;
163
+ }
164
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}