@cortexkit/common-auth 0.2.1 → 0.2.2

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.
@@ -9,6 +9,13 @@ export interface RowOperationOptions {
9
9
  onFailure?: FailureHook;
10
10
  /** The provider-wide lock, when an operation may change identity keying. */
11
11
  providerLock?: PoolLockSpec;
12
+ /**
13
+ * Further locks taken after the row lock and the provider-wide lock, in
14
+ * this order, before the store locks: the same place `refresh` takes its
15
+ * extra locks, so a caller holding legacy locks around a row write and a
16
+ * refresh of that row acquire them in one order and cannot deadlock.
17
+ */
18
+ extraLocks?: readonly PoolLockSpec[];
12
19
  }
13
20
  export interface AddInput {
14
21
  id: string;
@@ -78,6 +78,8 @@ export async function addRow(rt, input, options = {}) {
78
78
  await locks.acquire(rowLockSpec(rt, { id, identity }));
79
79
  if (credential.type === 'oauth')
80
80
  await locks.acquire(options.providerLock ?? rt.providerLock);
81
+ for (const extra of options.extraLocks ?? [])
82
+ await locks.acquire(extra);
81
83
  return withTransaction(ctx, locks, progress, { operation: 'add', rowId: id }, async (tx) => {
82
84
  const rows = tx.rows();
83
85
  const fingerprint = fingerprintOf(credential);
@@ -150,6 +152,8 @@ export async function replaceRow(rt, id, credential, input = {}, options = {}) {
150
152
  await locks.acquire(rowLockSpec(rt, seen));
151
153
  if (credential.type === 'oauth')
152
154
  await locks.acquire(options.providerLock ?? rt.providerLock);
155
+ for (const extra of options.extraLocks ?? [])
156
+ await locks.acquire(extra);
153
157
  return withTransaction(ctx, locks, progress, { operation: 'replace', rowId: id }, async (tx) => {
154
158
  const row = requireUsableRow('replace', id, tx.row(id), credential);
155
159
  if (rowLockKey(row) !== rowLockKey(seen))
@@ -197,6 +201,8 @@ export async function rotateRow(rt, id, credential, input = {}, options = {}) {
197
201
  await locks.acquire(rowLockSpec(rt, seen));
198
202
  if (input.identity !== undefined && credential.type === 'oauth')
199
203
  await locks.acquire(options.providerLock ?? rt.providerLock);
204
+ for (const extra of options.extraLocks ?? [])
205
+ await locks.acquire(extra);
200
206
  return withTransaction(ctx, locks, progress, { operation: 'rotate', rowId: id }, async (tx) => {
201
207
  const row = requireUsableRow('rotate', id, tx.row(id), credential);
202
208
  if (rowLockKey(row) !== rowLockKey(seen))
@@ -238,6 +244,8 @@ export async function recordRowIdentity(rt, id, identity, options = {}) {
238
244
  const { row: seen } = await readRow(rt, 'recordIdentity', id);
239
245
  await locks.acquire(rowLockSpec(rt, seen));
240
246
  await locks.acquire(options.providerLock ?? rt.providerLock);
247
+ for (const extra of options.extraLocks ?? [])
248
+ await locks.acquire(extra);
241
249
  return withTransaction(rt.ctx, locks, progress, { operation: 'recordIdentity', rowId: id }, async (tx) => {
242
250
  const row = requireUsableRow('recordIdentity', id, tx.row(id));
243
251
  if (rowLockKey(row) !== rowLockKey(seen))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cortexkit/common-auth",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
4
4
  "description": "Shared plumbing for the CortexKit auth plugins: loopback RPC, file locks and atomic writes, logger, sidebar state file, TUI preferences and TUI build.",
5
5
  "license": "MIT",
6
6
  "repository": {