@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.
- package/CHANGELOG.md +12 -0
- package/dist/{dist-E4y3Hyed.mjs → dist-Dvcuof5S.mjs} +4126 -782
- package/dist/{dist-hxTUn06g.js → dist-xyaDmv1T.js} +4125 -787
- package/dist/oidc/auth-oidc.addon.js +81 -90
- package/dist/oidc/auth-oidc.addon.mjs +81 -90
- package/dist/webauthn/_stub.js +1 -1
- package/dist/webauthn/{_virtual_mf-localSharedImportMap___mfe_internal__addon_auth_webauthn_widgets-Dbb4FfU4.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_auth_webauthn_widgets-U5-CdChb.mjs} +2 -2
- package/dist/webauthn/_virtual_mf___mfe_internal__addon_auth_webauthn_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-CQJ6wKXR.mjs +26 -0
- package/dist/webauthn/auth-webauthn.addon.js +1 -1
- package/dist/webauthn/auth-webauthn.addon.mjs +1 -1
- package/dist/webauthn/{hostInit-Bc063UIg.mjs → hostInit-D-l58LQN.mjs} +2 -2
- package/dist/webauthn/remoteEntry.js +1 -1
- package/package.json +1 -1
- package/dist/webauthn/_virtual_mf___mfe_internal__addon_auth_webauthn_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-CjbhzhqS.mjs +0 -26
|
@@ -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-
|
|
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
|
-
|
|
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
|
-
|
|
934
|
-
|
|
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
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
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.
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
}
|
|
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
|
-
|
|
1206
|
-
|
|
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
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
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"
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
929
|
-
|
|
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
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
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.
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
}
|
|
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
|
-
|
|
1201
|
-
|
|
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
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
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"
|
|
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
|
});
|
package/dist/webauthn/_stub.js
CHANGED
|
@@ -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-
|
|
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.
|
|
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.
|
|
36
|
+
version: "1.2.357",
|
|
37
37
|
scope: ["default"],
|
|
38
38
|
loaded: !1,
|
|
39
39
|
from: "addon_auth_webauthn_widgets",
|