@camstack/addon-auth 1.2.170 → 1.2.172

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.
@@ -2,7 +2,7 @@ Object.defineProperties(exports, {
2
2
  __esModule: { value: true },
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
- const require_dist = require("../dist-hxTUn06g.js");
5
+ const require_dist = require("../dist-xyaDmv1T.js");
6
6
  let node_crypto = require("node:crypto");
7
7
  node_crypto = require_dist.__toESM(node_crypto);
8
8
  //#region ../../node_modules/jose/dist/webapi/lib/buffer_utils.js
@@ -805,8 +805,7 @@ function findOidcProvider(config, id) {
805
805
  return config.providers.find((p) => p.id === id) ?? null;
806
806
  }
807
807
  function connectionConfigured(row) {
808
- const secret = typeof row.clientSecret === "string" ? row.clientSecret.trim() : "";
809
- return row.clientId.trim() !== "" && secret !== "";
808
+ return row.clientId.trim() !== "";
810
809
  }
811
810
  function clientSecretView(clientSecret, secrets, connectionId) {
812
811
  if (require_dist.isSecretMarker(clientSecret)) return require_dist.toSecretFieldView(clientSecret);
@@ -868,16 +867,6 @@ function updateOidcConnection(config, id, patch) {
868
867
  clearClientSecret: patch.clearClientSecret === true
869
868
  };
870
869
  }
871
- function deleteOidcConnection(config, id) {
872
- if (!config.providers.some((p) => p.id === id)) return {
873
- ok: false,
874
- reason: "not-found"
875
- };
876
- return {
877
- ok: true,
878
- config: { providers: config.providers.filter((p) => p.id !== id) }
879
- };
880
- }
881
870
  /** Map a wire `clientSecret` field into an update patch fragment. */
882
871
  function clientSecretPatchOf(value) {
883
872
  if (value === void 0) return {};
@@ -898,7 +887,7 @@ var OidcProviderBodySchema = require_dist.object({
898
887
  icon: require_dist.string(),
899
888
  issuerUrl: require_dist.string(),
900
889
  clientId: require_dist.string(),
901
- clientSecret: require_dist.string().meta({ secret: true }),
890
+ clientSecret: require_dist.string().optional().meta({ secret: true }),
902
891
  redirectUri: require_dist.string(),
903
892
  scopes: require_dist.string(),
904
893
  usernameClaim: usernameClaimSchema
@@ -918,6 +907,14 @@ function rowToProvider(id, data) {
918
907
  id
919
908
  };
920
909
  }
910
+ /** The stored body of a row; an empty or non-text secret is left out. */
911
+ function bodyOf(row) {
912
+ const { id: _id, clientSecret, ...rest } = row;
913
+ return typeof clientSecret === "string" && clientSecret !== "" ? {
914
+ ...rest,
915
+ clientSecret
916
+ } : rest;
917
+ }
921
918
  var OidcProviderStore = class OidcProviderStore {
922
919
  kind;
923
920
  constructor(kind) {
@@ -930,42 +927,60 @@ var OidcProviderStore = class OidcProviderStore {
930
927
  const page = await this.kind.query({ limit: 1e3 });
931
928
  const out = [];
932
929
  for (const record of page.records) {
933
- let data = record.data;
934
- try {
935
- const resolved = await this.kind.getResolved(record.id);
936
- if (resolved !== null) data = resolved.data;
937
- } catch (err) {
938
- if (!(err instanceof require_dist.RecordSecretUnavailableError)) throw err;
939
- }
940
- const parsed = OidcProviderBodySchema.safeParse(data);
941
- if (!parsed.success) continue;
942
- out.push(rowToProvider(record.id, parsed.data));
930
+ const row = await this.getResolved(record.id);
931
+ if (row !== null) out.push(row);
943
932
  }
944
933
  return out;
945
934
  }
946
- async replaceAll(providers) {
947
- const page = await this.kind.query({ limit: 1e3 });
948
- const nextIds = new Set(providers.map((p) => p.id));
949
- for (const row of page.records) if (!nextIds.has(row.id)) await this.kind.delete(row.id);
950
- for (const row of providers) {
951
- const { id, displayName, icon, issuerUrl, clientId, clientSecret, redirectUri, scopes, usernameClaim } = row;
952
- const body = {
953
- displayName,
954
- icon,
955
- issuerUrl,
956
- clientId,
957
- clientSecret,
958
- redirectUri,
959
- scopes,
960
- usernameClaim
935
+ /** One row with its secret resolved for the runtime token call; null when absent. */
936
+ async getResolved(id) {
937
+ let record;
938
+ try {
939
+ record = await this.kind.getResolved(id);
940
+ } catch (err) {
941
+ if (!(err instanceof require_dist.RecordSecretUnavailableError)) throw err;
942
+ const stored = await this.kind.get(id);
943
+ if (stored === null) return null;
944
+ const { clientSecret: _unreadable, ...rest } = stored.data;
945
+ record = {
946
+ ...stored,
947
+ data: rest
961
948
  };
962
- const parsed = oidcProviderEntryKind.schema.safeParse(body);
963
- if (!parsed.success) throw new Error(`invalid OIDC provider '${id}': ${parsed.error.message}`);
964
- await this.kind.put({
965
- id,
966
- data: parsed.data
967
- });
968
949
  }
950
+ if (record === null) return null;
951
+ const parsed = OidcProviderBodySchema.safeParse(record.data);
952
+ return parsed.success ? rowToProvider(id, parsed.data) : null;
953
+ }
954
+ /**
955
+ * Insert ONE new row (`ifRev: 0`: an existing id is refused). A plaintext
956
+ * `clientSecret` is stored by the records facade under the row's own ref.
957
+ */
958
+ async create(row) {
959
+ const body = bodyOf(row);
960
+ const parsed = OidcProviderBodySchema.safeParse(body);
961
+ if (!parsed.success) throw new Error(`invalid OIDC provider '${row.id}': ${parsed.error.message}`);
962
+ await this.kind.put({
963
+ id: row.id,
964
+ data: parsed.data
965
+ }, { ifRev: 0 });
966
+ return this.requireRow(row.id);
967
+ }
968
+ /**
969
+ * Merge a partial into ONE row. `clientSecret`: a plaintext sets it, `undefined`
970
+ * keeps the stored one, `null` clears it.
971
+ */
972
+ async update(id, partial) {
973
+ await this.kind.patch(id, partial);
974
+ return this.requireRow(id);
975
+ }
976
+ /** Delete one provider record; no other row (nor its secrets) is touched. */
977
+ async remove(id) {
978
+ await this.kind.delete(id);
979
+ }
980
+ async requireRow(id) {
981
+ const row = await this.getResolved(id);
982
+ if (row === null) throw new Error(`OIDC provider '${id}' is not readable after the write`);
983
+ return row;
969
984
  }
970
985
  };
971
986
  //#endregion
@@ -1070,7 +1085,7 @@ var AuthOidcAddon = class extends require_dist.BaseAddon {
1070
1085
  super({ ...DEFAULT_CONFIG });
1071
1086
  }
1072
1087
  async onConfigChanged() {
1073
- this.activeProviders = await this.loadPersistedProviders();
1088
+ if (this.providerStore !== null) this.activeProviders = await this.providerStore.listResolved();
1074
1089
  this.rebuildInstances();
1075
1090
  }
1076
1091
  async onInitialize() {
@@ -1078,16 +1093,7 @@ var AuthOidcAddon = class extends require_dist.BaseAddon {
1078
1093
  if (records === void 0) throw new Error("auth-oidc: ctx.records is required (hub-only addon)");
1079
1094
  await records.declare({ "oidc-provider": oidcProviderEntryKind });
1080
1095
  this.providerStore = OidcProviderStore.of(records);
1081
- this.activeProviders = await this.loadPersistedProviders();
1082
- if ((await this.providerStore.listResolved()).length === 0 && this.config.providers.length > 0) try {
1083
- await this.providerStore.replaceAll(this.config.providers);
1084
- this.activeProviders = await this.loadPersistedProviders();
1085
- } catch (err) {
1086
- const msg = err instanceof Error ? err.message : String(err);
1087
- if (!msg.startsWith("records/foreign-marker:")) throw err;
1088
- this.ctx.logger.warn("OIDC: deferred config→records copy (a secret marker is bound to another row)", { meta: { error: msg } });
1089
- this.activeProviders = [...this.config.providers];
1090
- }
1096
+ this.activeProviders = await this.providerStore.listResolved();
1091
1097
  this.rebuildInstances();
1092
1098
  const authProvider = {
1093
1099
  validateCredentials: async () => null,
@@ -1173,7 +1179,10 @@ var AuthOidcAddon = class extends require_dist.BaseAddon {
1173
1179
  createConnection: async (input) => {
1174
1180
  const result = createOidcConnection(this.providersConfig(), input);
1175
1181
  if (!result.ok) throw new Error(result.reason === "duplicate-id" ? `An OIDC connection with id "${input.id}" already exists` : `Invalid connection id "${input.id}" — use a lowercase slug`);
1176
- await this.persistProviders(result.config.providers);
1182
+ const row = result.config.providers.find((p) => p.id === result.id);
1183
+ if (row === void 0) throw new Error(`Invalid connection id "${input.id}"`);
1184
+ const stored = await this.requireStore().create(row);
1185
+ this.activeProviders = [...this.activeProviders, stored];
1177
1186
  this.rebuildInstances();
1178
1187
  return { id: result.id };
1179
1188
  },
@@ -1190,26 +1199,21 @@ var AuthOidcAddon = class extends require_dist.BaseAddon {
1190
1199
  ...input.usernameClaim !== void 0 ? { usernameClaim: input.usernameClaim } : {}
1191
1200
  });
1192
1201
  if (!result.ok) throw new Error(`Unknown OIDC connection "${input.id}"`);
1193
- if (result.clearClientSecret) {
1194
- const cleared = result.config.providers.map((p) => p.id === input.id ? {
1195
- ...p,
1196
- clientSecret: require_dist.SECRET_CLEAR
1197
- } : p);
1198
- await this.persistProviders(cleared);
1199
- } else await this.persistProviders(result.config.providers);
1202
+ const next = result.config.providers.find((p) => p.id === input.id);
1203
+ if (next === void 0) throw new Error(`Unknown OIDC connection "${input.id}"`);
1204
+ const { id: _id, clientSecret: _carried, ...fields } = next;
1205
+ const stored = await this.requireStore().update(input.id, {
1206
+ ...fields,
1207
+ ...result.clearClientSecret ? { clientSecret: null } : secretPatch.clientSecret !== void 0 ? { clientSecret: secretPatch.clientSecret } : {}
1208
+ });
1209
+ this.activeProviders = this.activeProviders.map((p) => p.id === input.id ? stored : p);
1200
1210
  this.rebuildInstances();
1201
1211
  return { ok: true };
1202
1212
  },
1203
1213
  deleteConnection: async (input) => {
1204
1214
  if (findOidcProvider(this.providersConfig(), input.id) === null) throw new Error(`Unknown OIDC connection "${input.id}"`);
1205
- const cleared = this.activeProviders.map((p) => p.id === input.id ? {
1206
- ...p,
1207
- clientSecret: require_dist.SECRET_CLEAR
1208
- } : p);
1209
- await this.persistProviders(cleared);
1210
- const result = deleteOidcConnection(this.providersConfig(), input.id);
1211
- if (!result.ok) throw new Error(`Unknown OIDC connection "${input.id}"`);
1212
- await this.persistProviders(result.config.providers);
1215
+ await this.requireStore().remove(input.id);
1216
+ this.activeProviders = this.activeProviders.filter((p) => p.id !== input.id);
1213
1217
  this.rebuildInstances();
1214
1218
  return { ok: true };
1215
1219
  }
@@ -1251,22 +1255,9 @@ var AuthOidcAddon = class extends require_dist.BaseAddon {
1251
1255
  providersConfig() {
1252
1256
  return { providers: this.activeProviders };
1253
1257
  }
1254
- async loadPersistedProviders() {
1255
- const store = this.providerStore;
1256
- if (store !== null) {
1257
- const fromRecords = await store.listResolved();
1258
- if (fromRecords.length > 0) return fromRecords;
1259
- }
1260
- return this.config.providers;
1261
- }
1262
- async persistProviders(providers) {
1263
- this.activeProviders = [...providers];
1264
- const store = this.providerStore;
1265
- if (store !== null) {
1266
- await store.replaceAll(providers);
1267
- return;
1268
- }
1269
- await this.updateGlobalSettings({ providers: [...providers] });
1258
+ requireStore() {
1259
+ if (this.providerStore === null) throw new Error("auth-oidc: the records store is not ready");
1260
+ return this.providerStore;
1270
1261
  }
1271
1262
  rebuildInstances() {
1272
1263
  this.instances.clear();
@@ -1444,7 +1435,7 @@ var AuthOidcAddon = class extends require_dist.BaseAddon {
1444
1435
  if (!inst) throw new Error(`OIDC: provider "${providerId}" no longer configured`);
1445
1436
  const doc = await this.getDiscovery(providerId);
1446
1437
  const clientSecret = inst.config.clientSecret;
1447
- if (typeof clientSecret !== "string" || clientSecret.length === 0) throw new Error(`OIDC: client secret for "${providerId}" is unavailable`);
1438
+ if (typeof clientSecret !== "string") throw new Error(`OIDC: client secret for "${providerId}" is unavailable`);
1448
1439
  const tokenRes = await fetch(doc.token_endpoint, {
1449
1440
  method: "POST",
1450
1441
  headers: {
@@ -1456,7 +1447,7 @@ var AuthOidcAddon = class extends require_dist.BaseAddon {
1456
1447
  code,
1457
1448
  redirect_uri: pending.redirectUri,
1458
1449
  client_id: inst.config.clientId,
1459
- client_secret: clientSecret,
1450
+ ...clientSecret.length > 0 ? { client_secret: clientSecret } : {},
1460
1451
  code_verifier: pending.codeVerifier
1461
1452
  })
1462
1453
  });
@@ -1,4 +1,4 @@
1
- import { A as toSecretFieldView, C as SECRET_CLEAR, D as globalSecretScope, F as object, I as string, O as isSecretClear, S as RecordSecretUnavailableError, T as defineEntryKind, _ as requestMountPrefix, b as errMsg, c as authProviderCapability, d as loginMethodCapability, f as normalizeOrigin, g as pickRequestOrigin, h as parseAppPageLang, i as addonRoutesCapability, j as _enum, k as isSecretMarker, l as buildAddonRouteProvider, m as parseAppFlowRequest, n as APP_REFUSED_PATH, o as advertisedHubOrigins, p as oidcConnectionsCapability, r as SSO_STATE_COOKIE, s as appFlowLocation, t as APP_FLOW_DEFAULT_REDIRECT, u as claimedRequestOrigins, v as resolveIconKey, w as arrayItemFieldPath, x as BaseAddon } from "../dist-E4y3Hyed.mjs";
1
+ import { A as _enum, C as arrayItemFieldPath, D as isSecretClear, E as globalSecretScope, F as string, O as isSecretMarker, P as object, S as RecordSecretUnavailableError, _ as requestMountPrefix, b as errMsg, c as authProviderCapability, d as loginMethodCapability, f as normalizeOrigin, g as pickRequestOrigin, h as parseAppPageLang, i as addonRoutesCapability, k as toSecretFieldView, l as buildAddonRouteProvider, m as parseAppFlowRequest, n as APP_REFUSED_PATH, o as advertisedHubOrigins, p as oidcConnectionsCapability, r as SSO_STATE_COOKIE, s as appFlowLocation, t as APP_FLOW_DEFAULT_REDIRECT, u as claimedRequestOrigins, v as resolveIconKey, w as defineEntryKind, x as BaseAddon } from "../dist-Dvcuof5S.mjs";
2
2
  import * as crypto$1 from "node:crypto";
3
3
  //#region ../../node_modules/jose/dist/webapi/lib/buffer_utils.js
4
4
  var encoder = new TextEncoder(), decoder = new TextDecoder(), strictDecoder = new TextDecoder("utf-8", { fatal: !0 });
@@ -800,8 +800,7 @@ function findOidcProvider(config, id) {
800
800
  return config.providers.find((p) => p.id === id) ?? null;
801
801
  }
802
802
  function connectionConfigured(row) {
803
- const secret = typeof row.clientSecret === "string" ? row.clientSecret.trim() : "";
804
- return row.clientId.trim() !== "" && secret !== "";
803
+ return row.clientId.trim() !== "";
805
804
  }
806
805
  function clientSecretView(clientSecret, secrets, connectionId) {
807
806
  if (isSecretMarker(clientSecret)) return toSecretFieldView(clientSecret);
@@ -863,16 +862,6 @@ function updateOidcConnection(config, id, patch) {
863
862
  clearClientSecret: patch.clearClientSecret === true
864
863
  };
865
864
  }
866
- function deleteOidcConnection(config, id) {
867
- if (!config.providers.some((p) => p.id === id)) return {
868
- ok: false,
869
- reason: "not-found"
870
- };
871
- return {
872
- ok: true,
873
- config: { providers: config.providers.filter((p) => p.id !== id) }
874
- };
875
- }
876
865
  /** Map a wire `clientSecret` field into an update patch fragment. */
877
866
  function clientSecretPatchOf(value) {
878
867
  if (value === void 0) return {};
@@ -893,7 +882,7 @@ var OidcProviderBodySchema = object({
893
882
  icon: string(),
894
883
  issuerUrl: string(),
895
884
  clientId: string(),
896
- clientSecret: string().meta({ secret: true }),
885
+ clientSecret: string().optional().meta({ secret: true }),
897
886
  redirectUri: string(),
898
887
  scopes: string(),
899
888
  usernameClaim: usernameClaimSchema
@@ -913,6 +902,14 @@ function rowToProvider(id, data) {
913
902
  id
914
903
  };
915
904
  }
905
+ /** The stored body of a row; an empty or non-text secret is left out. */
906
+ function bodyOf(row) {
907
+ const { id: _id, clientSecret, ...rest } = row;
908
+ return typeof clientSecret === "string" && clientSecret !== "" ? {
909
+ ...rest,
910
+ clientSecret
911
+ } : rest;
912
+ }
916
913
  var OidcProviderStore = class OidcProviderStore {
917
914
  kind;
918
915
  constructor(kind) {
@@ -925,42 +922,60 @@ var OidcProviderStore = class OidcProviderStore {
925
922
  const page = await this.kind.query({ limit: 1e3 });
926
923
  const out = [];
927
924
  for (const record of page.records) {
928
- let data = record.data;
929
- try {
930
- const resolved = await this.kind.getResolved(record.id);
931
- if (resolved !== null) data = resolved.data;
932
- } catch (err) {
933
- if (!(err instanceof RecordSecretUnavailableError)) throw err;
934
- }
935
- const parsed = OidcProviderBodySchema.safeParse(data);
936
- if (!parsed.success) continue;
937
- out.push(rowToProvider(record.id, parsed.data));
925
+ const row = await this.getResolved(record.id);
926
+ if (row !== null) out.push(row);
938
927
  }
939
928
  return out;
940
929
  }
941
- async replaceAll(providers) {
942
- const page = await this.kind.query({ limit: 1e3 });
943
- const nextIds = new Set(providers.map((p) => p.id));
944
- for (const row of page.records) if (!nextIds.has(row.id)) await this.kind.delete(row.id);
945
- for (const row of providers) {
946
- const { id, displayName, icon, issuerUrl, clientId, clientSecret, redirectUri, scopes, usernameClaim } = row;
947
- const body = {
948
- displayName,
949
- icon,
950
- issuerUrl,
951
- clientId,
952
- clientSecret,
953
- redirectUri,
954
- scopes,
955
- usernameClaim
930
+ /** One row with its secret resolved for the runtime token call; null when absent. */
931
+ async getResolved(id) {
932
+ let record;
933
+ try {
934
+ record = await this.kind.getResolved(id);
935
+ } catch (err) {
936
+ if (!(err instanceof RecordSecretUnavailableError)) throw err;
937
+ const stored = await this.kind.get(id);
938
+ if (stored === null) return null;
939
+ const { clientSecret: _unreadable, ...rest } = stored.data;
940
+ record = {
941
+ ...stored,
942
+ data: rest
956
943
  };
957
- const parsed = oidcProviderEntryKind.schema.safeParse(body);
958
- if (!parsed.success) throw new Error(`invalid OIDC provider '${id}': ${parsed.error.message}`);
959
- await this.kind.put({
960
- id,
961
- data: parsed.data
962
- });
963
944
  }
945
+ if (record === null) return null;
946
+ const parsed = OidcProviderBodySchema.safeParse(record.data);
947
+ return parsed.success ? rowToProvider(id, parsed.data) : null;
948
+ }
949
+ /**
950
+ * Insert ONE new row (`ifRev: 0`: an existing id is refused). A plaintext
951
+ * `clientSecret` is stored by the records facade under the row's own ref.
952
+ */
953
+ async create(row) {
954
+ const body = bodyOf(row);
955
+ const parsed = OidcProviderBodySchema.safeParse(body);
956
+ if (!parsed.success) throw new Error(`invalid OIDC provider '${row.id}': ${parsed.error.message}`);
957
+ await this.kind.put({
958
+ id: row.id,
959
+ data: parsed.data
960
+ }, { ifRev: 0 });
961
+ return this.requireRow(row.id);
962
+ }
963
+ /**
964
+ * Merge a partial into ONE row. `clientSecret`: a plaintext sets it, `undefined`
965
+ * keeps the stored one, `null` clears it.
966
+ */
967
+ async update(id, partial) {
968
+ await this.kind.patch(id, partial);
969
+ return this.requireRow(id);
970
+ }
971
+ /** Delete one provider record; no other row (nor its secrets) is touched. */
972
+ async remove(id) {
973
+ await this.kind.delete(id);
974
+ }
975
+ async requireRow(id) {
976
+ const row = await this.getResolved(id);
977
+ if (row === null) throw new Error(`OIDC provider '${id}' is not readable after the write`);
978
+ return row;
964
979
  }
965
980
  };
966
981
  //#endregion
@@ -1065,7 +1080,7 @@ var AuthOidcAddon = class extends BaseAddon {
1065
1080
  super({ ...DEFAULT_CONFIG });
1066
1081
  }
1067
1082
  async onConfigChanged() {
1068
- this.activeProviders = await this.loadPersistedProviders();
1083
+ if (this.providerStore !== null) this.activeProviders = await this.providerStore.listResolved();
1069
1084
  this.rebuildInstances();
1070
1085
  }
1071
1086
  async onInitialize() {
@@ -1073,16 +1088,7 @@ var AuthOidcAddon = class extends BaseAddon {
1073
1088
  if (records === void 0) throw new Error("auth-oidc: ctx.records is required (hub-only addon)");
1074
1089
  await records.declare({ "oidc-provider": oidcProviderEntryKind });
1075
1090
  this.providerStore = OidcProviderStore.of(records);
1076
- this.activeProviders = await this.loadPersistedProviders();
1077
- if ((await this.providerStore.listResolved()).length === 0 && this.config.providers.length > 0) try {
1078
- await this.providerStore.replaceAll(this.config.providers);
1079
- this.activeProviders = await this.loadPersistedProviders();
1080
- } catch (err) {
1081
- const msg = err instanceof Error ? err.message : String(err);
1082
- if (!msg.startsWith("records/foreign-marker:")) throw err;
1083
- this.ctx.logger.warn("OIDC: deferred config→records copy (a secret marker is bound to another row)", { meta: { error: msg } });
1084
- this.activeProviders = [...this.config.providers];
1085
- }
1091
+ this.activeProviders = await this.providerStore.listResolved();
1086
1092
  this.rebuildInstances();
1087
1093
  const authProvider = {
1088
1094
  validateCredentials: async () => null,
@@ -1168,7 +1174,10 @@ var AuthOidcAddon = class extends BaseAddon {
1168
1174
  createConnection: async (input) => {
1169
1175
  const result = createOidcConnection(this.providersConfig(), input);
1170
1176
  if (!result.ok) throw new Error(result.reason === "duplicate-id" ? `An OIDC connection with id "${input.id}" already exists` : `Invalid connection id "${input.id}" — use a lowercase slug`);
1171
- await this.persistProviders(result.config.providers);
1177
+ const row = result.config.providers.find((p) => p.id === result.id);
1178
+ if (row === void 0) throw new Error(`Invalid connection id "${input.id}"`);
1179
+ const stored = await this.requireStore().create(row);
1180
+ this.activeProviders = [...this.activeProviders, stored];
1172
1181
  this.rebuildInstances();
1173
1182
  return { id: result.id };
1174
1183
  },
@@ -1185,26 +1194,21 @@ var AuthOidcAddon = class extends BaseAddon {
1185
1194
  ...input.usernameClaim !== void 0 ? { usernameClaim: input.usernameClaim } : {}
1186
1195
  });
1187
1196
  if (!result.ok) throw new Error(`Unknown OIDC connection "${input.id}"`);
1188
- if (result.clearClientSecret) {
1189
- const cleared = result.config.providers.map((p) => p.id === input.id ? {
1190
- ...p,
1191
- clientSecret: SECRET_CLEAR
1192
- } : p);
1193
- await this.persistProviders(cleared);
1194
- } else await this.persistProviders(result.config.providers);
1197
+ const next = result.config.providers.find((p) => p.id === input.id);
1198
+ if (next === void 0) throw new Error(`Unknown OIDC connection "${input.id}"`);
1199
+ const { id: _id, clientSecret: _carried, ...fields } = next;
1200
+ const stored = await this.requireStore().update(input.id, {
1201
+ ...fields,
1202
+ ...result.clearClientSecret ? { clientSecret: null } : secretPatch.clientSecret !== void 0 ? { clientSecret: secretPatch.clientSecret } : {}
1203
+ });
1204
+ this.activeProviders = this.activeProviders.map((p) => p.id === input.id ? stored : p);
1195
1205
  this.rebuildInstances();
1196
1206
  return { ok: true };
1197
1207
  },
1198
1208
  deleteConnection: async (input) => {
1199
1209
  if (findOidcProvider(this.providersConfig(), input.id) === null) throw new Error(`Unknown OIDC connection "${input.id}"`);
1200
- const cleared = this.activeProviders.map((p) => p.id === input.id ? {
1201
- ...p,
1202
- clientSecret: SECRET_CLEAR
1203
- } : p);
1204
- await this.persistProviders(cleared);
1205
- const result = deleteOidcConnection(this.providersConfig(), input.id);
1206
- if (!result.ok) throw new Error(`Unknown OIDC connection "${input.id}"`);
1207
- await this.persistProviders(result.config.providers);
1210
+ await this.requireStore().remove(input.id);
1211
+ this.activeProviders = this.activeProviders.filter((p) => p.id !== input.id);
1208
1212
  this.rebuildInstances();
1209
1213
  return { ok: true };
1210
1214
  }
@@ -1246,22 +1250,9 @@ var AuthOidcAddon = class extends BaseAddon {
1246
1250
  providersConfig() {
1247
1251
  return { providers: this.activeProviders };
1248
1252
  }
1249
- async loadPersistedProviders() {
1250
- const store = this.providerStore;
1251
- if (store !== null) {
1252
- const fromRecords = await store.listResolved();
1253
- if (fromRecords.length > 0) return fromRecords;
1254
- }
1255
- return this.config.providers;
1256
- }
1257
- async persistProviders(providers) {
1258
- this.activeProviders = [...providers];
1259
- const store = this.providerStore;
1260
- if (store !== null) {
1261
- await store.replaceAll(providers);
1262
- return;
1263
- }
1264
- await this.updateGlobalSettings({ providers: [...providers] });
1253
+ requireStore() {
1254
+ if (this.providerStore === null) throw new Error("auth-oidc: the records store is not ready");
1255
+ return this.providerStore;
1265
1256
  }
1266
1257
  rebuildInstances() {
1267
1258
  this.instances.clear();
@@ -1439,7 +1430,7 @@ var AuthOidcAddon = class extends BaseAddon {
1439
1430
  if (!inst) throw new Error(`OIDC: provider "${providerId}" no longer configured`);
1440
1431
  const doc = await this.getDiscovery(providerId);
1441
1432
  const clientSecret = inst.config.clientSecret;
1442
- if (typeof clientSecret !== "string" || clientSecret.length === 0) throw new Error(`OIDC: client secret for "${providerId}" is unavailable`);
1433
+ if (typeof clientSecret !== "string") throw new Error(`OIDC: client secret for "${providerId}" is unavailable`);
1443
1434
  const tokenRes = await fetch(doc.token_endpoint, {
1444
1435
  method: "POST",
1445
1436
  headers: {
@@ -1451,7 +1442,7 @@ var AuthOidcAddon = class extends BaseAddon {
1451
1442
  code,
1452
1443
  redirect_uri: pending.redirectUri,
1453
1444
  client_id: inst.config.clientId,
1454
- client_secret: clientSecret,
1445
+ ...clientSecret.length > 0 ? { client_secret: clientSecret } : {},
1455
1446
  code_verifier: pending.codeVerifier
1456
1447
  })
1457
1448
  });
@@ -1,6 +1,6 @@
1
1
  import { n as e, r as t, t as n } from "./_virtual_mf___mfe_internal__addon_auth_webauthn_widgets__loadShare__react__loadShare__.js-BIIa6vDX.mjs";
2
2
  import { n as r, t as i } from "./_virtual_mf___mfe_internal__addon_auth_webauthn_widgets__loadShare___mf_0_tanstack_mf_1_react_mf_2_query__loadShare__.js-CQ-aEQ9b.mjs";
3
- import { n as a, t as o } from "./_virtual_mf___mfe_internal__addon_auth_webauthn_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-CjbhzhqS.mjs";
3
+ import { n as a, t as o } from "./_virtual_mf___mfe_internal__addon_auth_webauthn_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-CQJ6wKXR.mjs";
4
4
  import { n as s, r as c, t as l } from "./_virtual_mf___mfe_internal__addon_auth_webauthn_widgets__loadShare__react_mf_1_jsx_mf_2_runtime__loadShare__.js-BL2etuqg.mjs";
5
5
  //#region ../../node_modules/lucide-react/dist/esm/shared/src/utils/mergeClasses.js
6
6
  var u = (...e) => e.filter((e, t, n) => !!e && e.trim() !== "" && n.indexOf(e) === t).join(" ").trim(), d = (e) => e.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase(), f = (e) => e.replace(/^([A-Z])|[\s-_]+(\w)/g, (e, t, n) => n ? n.toUpperCase() : t.toLowerCase()), p = (e) => {
@@ -18,7 +18,7 @@ var e = {
18
18
  },
19
19
  "@camstack/types": {
20
20
  name: "@camstack/types",
21
- version: "1.2.428",
21
+ version: "1.2.452",
22
22
  scope: ["default"],
23
23
  loaded: !1,
24
24
  from: "addon_auth_webauthn_widgets",
@@ -33,7 +33,7 @@ var e = {
33
33
  },
34
34
  "@camstack/ui-library": {
35
35
  name: "@camstack/ui-library",
36
- version: "1.2.337",
36
+ version: "1.2.357",
37
37
  scope: ["default"],
38
38
  loaded: !1,
39
39
  from: "addon_auth_webauthn_widgets",