@naylence/runtime 0.3.5-test.911 → 0.3.5-test.914

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 (31) hide show
  1. package/dist/browser/index.cjs +78 -166
  2. package/dist/browser/index.mjs +78 -166
  3. package/dist/cjs/naylence/fame/config/extended-fame-config.js +58 -2
  4. package/dist/cjs/naylence/fame/http/jwks-api-router.js +16 -18
  5. package/dist/cjs/naylence/fame/http/oauth2-server.js +28 -31
  6. package/dist/cjs/naylence/fame/http/oauth2-token-router.js +153 -8
  7. package/dist/cjs/naylence/fame/http/openid-configuration-router.js +30 -32
  8. package/dist/cjs/naylence/fame/node/admission/admission-profile-factory.js +18 -0
  9. package/dist/cjs/naylence/fame/security/crypto/providers/default-crypto-provider.js +0 -162
  10. package/dist/cjs/version.js +2 -2
  11. package/dist/esm/naylence/fame/config/extended-fame-config.js +58 -2
  12. package/dist/esm/naylence/fame/http/jwks-api-router.js +16 -17
  13. package/dist/esm/naylence/fame/http/oauth2-server.js +28 -31
  14. package/dist/esm/naylence/fame/http/oauth2-token-router.js +153 -8
  15. package/dist/esm/naylence/fame/http/openid-configuration-router.js +30 -31
  16. package/dist/esm/naylence/fame/node/admission/admission-profile-factory.js +18 -0
  17. package/dist/esm/naylence/fame/security/crypto/providers/default-crypto-provider.js +0 -162
  18. package/dist/esm/version.js +2 -2
  19. package/dist/node/index.cjs +78 -166
  20. package/dist/node/index.mjs +78 -166
  21. package/dist/node/node.cjs +305 -251
  22. package/dist/node/node.mjs +305 -251
  23. package/dist/types/naylence/fame/http/jwks-api-router.d.ts +8 -8
  24. package/dist/types/naylence/fame/http/oauth2-server.d.ts +3 -3
  25. package/dist/types/naylence/fame/http/oauth2-token-router.d.ts +5 -5
  26. package/dist/types/naylence/fame/http/openid-configuration-router.d.ts +8 -8
  27. package/dist/types/naylence/fame/security/crypto/providers/default-crypto-provider.d.ts +0 -1
  28. package/dist/types/version.d.ts +1 -1
  29. package/package.json +4 -6
  30. package/dist/esm/naylence/fame/fastapi/oauth2-server.js +0 -205
  31. package/dist/types/naylence/fame/fastapi/oauth2-server.d.ts +0 -22
@@ -8,9 +8,6 @@ var ed25519_js = require('@noble/curves/ed25519.js');
8
8
  var hkdf_js = require('@noble/hashes/hkdf.js');
9
9
  var sha2_js = require('@noble/hashes/sha2.js');
10
10
  var utils_js = require('@noble/hashes/utils.js');
11
- var asn1Schema = require('@peculiar/asn1-schema');
12
- var asn1X509 = require('@peculiar/asn1-x509');
13
- var asn1Csr = require('@peculiar/asn1-csr');
14
11
  var yaml = require('yaml');
15
12
  var fastify = require('fastify');
16
13
  var websocketPlugin = require('@fastify/websocket');
@@ -101,12 +98,12 @@ installProcessEnvShim();
101
98
  // --- END ENV SHIM ---
102
99
 
103
100
  // This file is auto-generated during build - do not edit manually
104
- // Generated from package.json version: 0.3.5-test.911
101
+ // Generated from package.json version: 0.3.5-test.914
105
102
  /**
106
103
  * The package version, injected at build time.
107
104
  * @internal
108
105
  */
109
- const VERSION = '0.3.5-test.911';
106
+ const VERSION = '0.3.5-test.914';
110
107
 
111
108
  /**
112
109
  * Fame protocol specific error classes with WebSocket close codes and proper inheritance.
@@ -13093,6 +13090,61 @@ const CONFIG_SEARCH_PATHS = [
13093
13090
  ];
13094
13091
  const fsModuleSpecifier = String.fromCharCode(102) + String.fromCharCode(115);
13095
13092
  let cachedFsModule = null;
13093
+ // Capture this module's URL without triggering TypeScript's import.meta restriction on CJS builds
13094
+ const currentModuleUrl = (() => {
13095
+ try {
13096
+ return (0, eval)('import.meta.url');
13097
+ }
13098
+ catch {
13099
+ return undefined;
13100
+ }
13101
+ })();
13102
+ let cachedNodeRequire = typeof require === 'function' ? require : null;
13103
+ function fileUrlToPath(url) {
13104
+ try {
13105
+ const parsed = new URL(url);
13106
+ if (parsed.protocol !== 'file:') {
13107
+ return null;
13108
+ }
13109
+ let pathname = parsed.pathname;
13110
+ if (typeof process !== 'undefined' &&
13111
+ process.platform === 'win32' &&
13112
+ pathname.startsWith('/')) {
13113
+ pathname = pathname.slice(1);
13114
+ }
13115
+ return decodeURIComponent(pathname);
13116
+ }
13117
+ catch {
13118
+ return null;
13119
+ }
13120
+ }
13121
+ function getNodeRequire() {
13122
+ if (cachedNodeRequire) {
13123
+ return cachedNodeRequire;
13124
+ }
13125
+ if (!isNode) {
13126
+ return null;
13127
+ }
13128
+ const processBinding = process.binding;
13129
+ if (typeof processBinding !== 'function') {
13130
+ return null;
13131
+ }
13132
+ try {
13133
+ const moduleWrap = processBinding('module_wrap');
13134
+ if (typeof moduleWrap?.createRequire !== 'function') {
13135
+ return null;
13136
+ }
13137
+ const modulePathFromUrl = currentModuleUrl
13138
+ ? fileUrlToPath(currentModuleUrl)
13139
+ : null;
13140
+ const requireSource = modulePathFromUrl ?? `${process.cwd()}/.naylence-require-shim.js`;
13141
+ cachedNodeRequire = moduleWrap.createRequire(requireSource);
13142
+ return cachedNodeRequire;
13143
+ }
13144
+ catch {
13145
+ return null;
13146
+ }
13147
+ }
13096
13148
  function getFsModule() {
13097
13149
  if (cachedFsModule) {
13098
13150
  return cachedFsModule;
@@ -13100,9 +13152,10 @@ function getFsModule() {
13100
13152
  if (!isNode) {
13101
13153
  throw new Error('File system access is not available in this environment');
13102
13154
  }
13103
- if (typeof require === 'function') {
13155
+ const nodeRequire = typeof require === 'function' ? require : getNodeRequire();
13156
+ if (nodeRequire) {
13104
13157
  try {
13105
- cachedFsModule = require(fsModuleSpecifier);
13158
+ cachedFsModule = nodeRequire(fsModuleSpecifier);
13106
13159
  return cachedFsModule;
13107
13160
  }
13108
13161
  catch (error) {
@@ -25478,11 +25531,6 @@ const DEFAULT_AUDIENCE = 'router-dev';
25478
25531
  const DEFAULT_TTL_SEC$1 = 3600;
25479
25532
  const DEFAULT_HMAC_SECRET_BYTES = 32;
25480
25533
  const ENCRYPTION_ALG = 'ECDH-ES';
25481
- const EXTENSION_REQUEST_OID = '1.2.840.113549.1.9.14';
25482
- const COMMON_NAME_OID = '2.5.4.3';
25483
- const ED25519_OID = '1.3.101.112';
25484
- const CSR_PEM_TAG = 'CERTIFICATE REQUEST';
25485
- const LOGICAL_URI_PREFIX = 'naylence://';
25486
25534
  function normalizeDefaultCryptoProviderOptions(options) {
25487
25535
  if (!options) {
25488
25536
  return {};
@@ -25748,76 +25796,6 @@ class DefaultCryptoProvider {
25748
25796
  has_chain: Boolean(certificateChainPem),
25749
25797
  });
25750
25798
  }
25751
- async createCsr(nodeId, physicalPath, logicals, subjectName) {
25752
- const trimmedNodeId = assertNonEmptyString(nodeId, 'nodeId');
25753
- const trimmedPhysicalPath = assertNonEmptyString(physicalPath, 'physicalPath');
25754
- try {
25755
- if (this.artifacts.signing.algorithm !== 'EdDSA') {
25756
- throw new Error('CSR creation only supported for Ed25519 signing keys in the default crypto provider');
25757
- }
25758
- const cryptoImpl = await ensureWebCrypto();
25759
- const privateKey = await cryptoImpl.subtle.importKey('pkcs8', pemToArrayBuffer(this.signingPrivatePem), {
25760
- name: 'Ed25519',
25761
- }, false, ['sign']);
25762
- const publicKeyDer = pemToArrayBuffer(this.signingPublicPem);
25763
- const subjectPkInfo = asn1Schema.AsnConvert.parse(publicKeyDer, asn1X509.SubjectPublicKeyInfo);
25764
- const sanitizedLogicals = Array.isArray(logicals)
25765
- ? logicals.filter((value) => typeof value === 'string' && value.trim().length > 0)
25766
- : [];
25767
- const commonName = typeof subjectName === 'string' && subjectName.trim().length > 0
25768
- ? subjectName.trim()
25769
- : trimmedNodeId;
25770
- const subject = buildSubjectName(commonName);
25771
- const attributes = new asn1Csr.Attributes();
25772
- if (sanitizedLogicals.length > 0) {
25773
- const san = new asn1X509.SubjectAlternativeName(sanitizedLogicals.map((logical) => new asn1X509.GeneralName({
25774
- uniformResourceIdentifier: `${LOGICAL_URI_PREFIX}${logical}`,
25775
- })));
25776
- const extensions = new asn1X509.Extensions([
25777
- new asn1X509.Extension({
25778
- extnID: asn1X509.id_ce_subjectAltName,
25779
- critical: false,
25780
- extnValue: new asn1Schema.OctetString(asn1Schema.AsnConvert.serialize(san)),
25781
- }),
25782
- ]);
25783
- attributes.push(new asn1X509.Attribute({
25784
- type: EXTENSION_REQUEST_OID,
25785
- values: [asn1Schema.AsnConvert.serialize(extensions)],
25786
- }));
25787
- }
25788
- const requestInfo = new asn1Csr.CertificationRequestInfo({
25789
- subject,
25790
- subjectPKInfo: subjectPkInfo,
25791
- attributes,
25792
- });
25793
- const requestInfoDer = asn1Schema.AsnConvert.serialize(requestInfo);
25794
- const signature = await cryptoImpl.subtle.sign('Ed25519', privateKey, requestInfoDer);
25795
- const certificationRequest = new asn1Csr.CertificationRequest({
25796
- certificationRequestInfo: requestInfo,
25797
- signatureAlgorithm: new asn1X509.AlgorithmIdentifier({
25798
- algorithm: ED25519_OID,
25799
- }),
25800
- signature: encodeBitString(signature),
25801
- });
25802
- certificationRequest.certificationRequestInfoRaw = requestInfoDer;
25803
- const csrDer = asn1Schema.AsnConvert.serialize(certificationRequest);
25804
- const csrPem = arrayBufferToPem(csrDer, CSR_PEM_TAG);
25805
- logger$v.debug('csr_created', {
25806
- node_id: trimmedNodeId,
25807
- physical_path: trimmedPhysicalPath,
25808
- logical_count: sanitizedLogicals.length,
25809
- });
25810
- return csrPem;
25811
- }
25812
- catch (error) {
25813
- logger$v.error('csr_creation_failed', {
25814
- node_id: trimmedNodeId,
25815
- physical_path: trimmedPhysicalPath,
25816
- error: error instanceof Error ? error.message : String(error),
25817
- });
25818
- throw error;
25819
- }
25820
- }
25821
25799
  }
25822
25800
  async function buildProviderArtifacts(options) {
25823
25801
  const algorithm = normalizeAlgorithm(options.algorithm ?? readEnvAlgorithm());
@@ -26053,90 +26031,6 @@ function pemToDerBase64(pem) {
26053
26031
  // Ensure the output is valid base64 without whitespace
26054
26032
  return base64.replace(/\s+/g, '');
26055
26033
  }
26056
- let cryptoPromise = null;
26057
- async function ensureWebCrypto() {
26058
- if (typeof globalThis.crypto !== 'undefined' && globalThis.crypto?.subtle) {
26059
- return globalThis.crypto;
26060
- }
26061
- if (!cryptoPromise) {
26062
- if (typeof process !== 'undefined' &&
26063
- typeof process.versions?.node === 'string') {
26064
- cryptoPromise = import('node:crypto').then((module) => {
26065
- const webcrypto = module.webcrypto;
26066
- if (!webcrypto || !webcrypto.subtle) {
26067
- throw new Error('WebCrypto API is not available in this Node.js runtime');
26068
- }
26069
- globalThis.crypto = webcrypto;
26070
- return webcrypto;
26071
- });
26072
- }
26073
- else {
26074
- cryptoPromise = Promise.reject(new Error('WebCrypto API is not available in this environment'));
26075
- }
26076
- }
26077
- return cryptoPromise;
26078
- }
26079
- function pemToArrayBuffer(pem) {
26080
- const normalized = pem
26081
- .replace(/-----BEGIN[^-]+-----/g, '')
26082
- .replace(/-----END[^-]+-----/g, '')
26083
- .replace(/\s+/g, '');
26084
- const bytes = base64ToBytes$1(normalized);
26085
- return bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength);
26086
- }
26087
- function base64ToBytes$1(base64) {
26088
- if (typeof Buffer !== 'undefined') {
26089
- const buffer = Buffer.from(base64, 'base64');
26090
- const bytes = new Uint8Array(buffer.length);
26091
- for (let i = 0; i < buffer.length; i += 1) {
26092
- bytes[i] = buffer[i];
26093
- }
26094
- return bytes;
26095
- }
26096
- if (typeof atob === 'function') {
26097
- const binary = atob(base64);
26098
- const bytes = new Uint8Array(binary.length);
26099
- for (let i = 0; i < binary.length; i += 1) {
26100
- bytes[i] = binary.charCodeAt(i);
26101
- }
26102
- return bytes;
26103
- }
26104
- throw new Error('No base64 decoder available in this environment');
26105
- }
26106
- function arrayBufferToPem(buffer, tag) {
26107
- const base64 = bytesToBase64(new Uint8Array(buffer));
26108
- return `-----BEGIN ${tag}-----\n${formatPem(base64)}\n-----END ${tag}-----\n`;
26109
- }
26110
- function formatPem(base64) {
26111
- const lines = [];
26112
- for (let i = 0; i < base64.length; i += 64) {
26113
- lines.push(base64.slice(i, i + 64));
26114
- }
26115
- return lines.join('\n');
26116
- }
26117
- function encodeBitString(signature) {
26118
- const bytes = new Uint8Array(signature);
26119
- const bitString = new Uint8Array(bytes.length + 1);
26120
- bitString.set(bytes, 1);
26121
- return bitString.buffer;
26122
- }
26123
- function buildSubjectName(commonName) {
26124
- const attribute = new asn1X509.AttributeTypeAndValue({
26125
- type: COMMON_NAME_OID,
26126
- value: new asn1X509.AttributeValue({ utf8String: commonName }),
26127
- });
26128
- return new asn1X509.Name([new asn1X509.RelativeDistinguishedName([attribute])]);
26129
- }
26130
- function assertNonEmptyString(value, name) {
26131
- if (typeof value !== 'string') {
26132
- throw new TypeError(`${name} must be a string`);
26133
- }
26134
- const trimmed = value.trim();
26135
- if (trimmed.length === 0) {
26136
- throw new TypeError(`${name} must be a non-empty string`);
26137
- }
26138
- return trimmed;
26139
- }
26140
26034
  function cloneJson(value) {
26141
26035
  return JSON.parse(JSON.stringify(value));
26142
26036
  }
@@ -31778,6 +31672,8 @@ const ENV_VAR_DIRECT_INPAGE_CHANNEL = 'FAME_DIRECT_INPAGE_CHANNEL';
31778
31672
  const ENV_VAR_ADMISSION_SERVICE_URL = 'FAME_ADMISSION_SERVICE_URL';
31779
31673
  const DEFAULT_INPAGE_CHANNEL = 'naylence-fabric';
31780
31674
  const PROFILE_NAME_WELCOME = 'welcome';
31675
+ const PROFILE_NAME_WELCOME_PKCE = 'welcome-pkce';
31676
+ const PROFILE_NAME_WELCOME_PKCE_ALIAS = 'welcome_pkce';
31781
31677
  const PROFILE_NAME_DIRECT = 'direct';
31782
31678
  const PROFILE_NAME_DIRECT_HTTP = 'direct-http';
31783
31679
  const PROFILE_NAME_DIRECT_INPAGE = 'direct-inpage';
@@ -31838,6 +31734,7 @@ function createOAuthPkceTokenProviderConfig() {
31838
31734
  }
31839
31735
  const welcomeIsRoot = factory.Expressions.env(ENV_VAR_IS_ROOT, 'false');
31840
31736
  const welcomeTokenProvider = createOAuthTokenProviderConfig();
31737
+ const welcomePkceTokenProvider = createOAuthPkceTokenProviderConfig();
31841
31738
  const WELCOME_SERVICE_PROFILE = {
31842
31739
  type: 'WelcomeServiceClient',
31843
31740
  is_root: welcomeIsRoot,
@@ -31851,6 +31748,19 @@ const WELCOME_SERVICE_PROFILE = {
31851
31748
  tokenProvider: welcomeTokenProvider,
31852
31749
  },
31853
31750
  };
31751
+ const WELCOME_SERVICE_PKCE_PROFILE = {
31752
+ type: 'WelcomeServiceClient',
31753
+ is_root: welcomeIsRoot,
31754
+ isRoot: welcomeIsRoot,
31755
+ url: factory.Expressions.env(ENV_VAR_ADMISSION_SERVICE_URL),
31756
+ supported_transports: ['websocket'],
31757
+ supportedTransports: ['websocket'],
31758
+ auth: {
31759
+ type: 'BearerTokenHeaderAuth',
31760
+ token_provider: welcomePkceTokenProvider,
31761
+ tokenProvider: welcomePkceTokenProvider,
31762
+ },
31763
+ };
31854
31764
  const directGrantTokenProvider = createOAuthTokenProviderConfig();
31855
31765
  const directGrant = {
31856
31766
  type: 'WebSocketConnectionGrant',
@@ -31956,6 +31866,8 @@ const NOOP_PROFILE = {
31956
31866
  };
31957
31867
  const PROFILE_MAP$1 = {
31958
31868
  [PROFILE_NAME_WELCOME]: WELCOME_SERVICE_PROFILE,
31869
+ [PROFILE_NAME_WELCOME_PKCE]: WELCOME_SERVICE_PKCE_PROFILE,
31870
+ [PROFILE_NAME_WELCOME_PKCE_ALIAS]: WELCOME_SERVICE_PKCE_PROFILE,
31959
31871
  [PROFILE_NAME_DIRECT]: DIRECT_PROFILE,
31960
31872
  [PROFILE_NAME_DIRECT_PKCE]: DIRECT_PKCE_PROFILE,
31961
31873
  [PROFILE_NAME_DIRECT_PKCE_ALIAS]: DIRECT_PKCE_PROFILE,
@@ -7,9 +7,6 @@ import { x25519 } from '@noble/curves/ed25519.js';
7
7
  import { hkdf } from '@noble/hashes/hkdf.js';
8
8
  import { sha256, sha512 } from '@noble/hashes/sha2.js';
9
9
  import { utf8ToBytes, bytesToHex, randomBytes, concatBytes } from '@noble/hashes/utils.js';
10
- import { AsnConvert, OctetString } from '@peculiar/asn1-schema';
11
- import { SubjectPublicKeyInfo, SubjectAlternativeName, GeneralName, Extensions, Extension, id_ce_subjectAltName, Attribute, AlgorithmIdentifier, AttributeTypeAndValue, AttributeValue, Name, RelativeDistinguishedName } from '@peculiar/asn1-x509';
12
- import { Attributes, CertificationRequestInfo, CertificationRequest } from '@peculiar/asn1-csr';
13
10
  import { parse } from 'yaml';
14
11
  import fastify from 'fastify';
15
12
  import websocketPlugin from '@fastify/websocket';
@@ -99,12 +96,12 @@ installProcessEnvShim();
99
96
  // --- END ENV SHIM ---
100
97
 
101
98
  // This file is auto-generated during build - do not edit manually
102
- // Generated from package.json version: 0.3.5-test.911
99
+ // Generated from package.json version: 0.3.5-test.914
103
100
  /**
104
101
  * The package version, injected at build time.
105
102
  * @internal
106
103
  */
107
- const VERSION = '0.3.5-test.911';
104
+ const VERSION = '0.3.5-test.914';
108
105
 
109
106
  /**
110
107
  * Fame protocol specific error classes with WebSocket close codes and proper inheritance.
@@ -13091,6 +13088,61 @@ const CONFIG_SEARCH_PATHS = [
13091
13088
  ];
13092
13089
  const fsModuleSpecifier = String.fromCharCode(102) + String.fromCharCode(115);
13093
13090
  let cachedFsModule = null;
13091
+ // Capture this module's URL without triggering TypeScript's import.meta restriction on CJS builds
13092
+ const currentModuleUrl = (() => {
13093
+ try {
13094
+ return (0, eval)('import.meta.url');
13095
+ }
13096
+ catch {
13097
+ return undefined;
13098
+ }
13099
+ })();
13100
+ let cachedNodeRequire = typeof require === 'function' ? require : null;
13101
+ function fileUrlToPath(url) {
13102
+ try {
13103
+ const parsed = new URL(url);
13104
+ if (parsed.protocol !== 'file:') {
13105
+ return null;
13106
+ }
13107
+ let pathname = parsed.pathname;
13108
+ if (typeof process !== 'undefined' &&
13109
+ process.platform === 'win32' &&
13110
+ pathname.startsWith('/')) {
13111
+ pathname = pathname.slice(1);
13112
+ }
13113
+ return decodeURIComponent(pathname);
13114
+ }
13115
+ catch {
13116
+ return null;
13117
+ }
13118
+ }
13119
+ function getNodeRequire() {
13120
+ if (cachedNodeRequire) {
13121
+ return cachedNodeRequire;
13122
+ }
13123
+ if (!isNode) {
13124
+ return null;
13125
+ }
13126
+ const processBinding = process.binding;
13127
+ if (typeof processBinding !== 'function') {
13128
+ return null;
13129
+ }
13130
+ try {
13131
+ const moduleWrap = processBinding('module_wrap');
13132
+ if (typeof moduleWrap?.createRequire !== 'function') {
13133
+ return null;
13134
+ }
13135
+ const modulePathFromUrl = currentModuleUrl
13136
+ ? fileUrlToPath(currentModuleUrl)
13137
+ : null;
13138
+ const requireSource = modulePathFromUrl ?? `${process.cwd()}/.naylence-require-shim.js`;
13139
+ cachedNodeRequire = moduleWrap.createRequire(requireSource);
13140
+ return cachedNodeRequire;
13141
+ }
13142
+ catch {
13143
+ return null;
13144
+ }
13145
+ }
13094
13146
  function getFsModule() {
13095
13147
  if (cachedFsModule) {
13096
13148
  return cachedFsModule;
@@ -13098,9 +13150,10 @@ function getFsModule() {
13098
13150
  if (!isNode) {
13099
13151
  throw new Error('File system access is not available in this environment');
13100
13152
  }
13101
- if (typeof require === 'function') {
13153
+ const nodeRequire = typeof require === 'function' ? require : getNodeRequire();
13154
+ if (nodeRequire) {
13102
13155
  try {
13103
- cachedFsModule = require(fsModuleSpecifier);
13156
+ cachedFsModule = nodeRequire(fsModuleSpecifier);
13104
13157
  return cachedFsModule;
13105
13158
  }
13106
13159
  catch (error) {
@@ -25476,11 +25529,6 @@ const DEFAULT_AUDIENCE = 'router-dev';
25476
25529
  const DEFAULT_TTL_SEC$1 = 3600;
25477
25530
  const DEFAULT_HMAC_SECRET_BYTES = 32;
25478
25531
  const ENCRYPTION_ALG = 'ECDH-ES';
25479
- const EXTENSION_REQUEST_OID = '1.2.840.113549.1.9.14';
25480
- const COMMON_NAME_OID = '2.5.4.3';
25481
- const ED25519_OID = '1.3.101.112';
25482
- const CSR_PEM_TAG = 'CERTIFICATE REQUEST';
25483
- const LOGICAL_URI_PREFIX = 'naylence://';
25484
25532
  function normalizeDefaultCryptoProviderOptions(options) {
25485
25533
  if (!options) {
25486
25534
  return {};
@@ -25746,76 +25794,6 @@ class DefaultCryptoProvider {
25746
25794
  has_chain: Boolean(certificateChainPem),
25747
25795
  });
25748
25796
  }
25749
- async createCsr(nodeId, physicalPath, logicals, subjectName) {
25750
- const trimmedNodeId = assertNonEmptyString(nodeId, 'nodeId');
25751
- const trimmedPhysicalPath = assertNonEmptyString(physicalPath, 'physicalPath');
25752
- try {
25753
- if (this.artifacts.signing.algorithm !== 'EdDSA') {
25754
- throw new Error('CSR creation only supported for Ed25519 signing keys in the default crypto provider');
25755
- }
25756
- const cryptoImpl = await ensureWebCrypto();
25757
- const privateKey = await cryptoImpl.subtle.importKey('pkcs8', pemToArrayBuffer(this.signingPrivatePem), {
25758
- name: 'Ed25519',
25759
- }, false, ['sign']);
25760
- const publicKeyDer = pemToArrayBuffer(this.signingPublicPem);
25761
- const subjectPkInfo = AsnConvert.parse(publicKeyDer, SubjectPublicKeyInfo);
25762
- const sanitizedLogicals = Array.isArray(logicals)
25763
- ? logicals.filter((value) => typeof value === 'string' && value.trim().length > 0)
25764
- : [];
25765
- const commonName = typeof subjectName === 'string' && subjectName.trim().length > 0
25766
- ? subjectName.trim()
25767
- : trimmedNodeId;
25768
- const subject = buildSubjectName(commonName);
25769
- const attributes = new Attributes();
25770
- if (sanitizedLogicals.length > 0) {
25771
- const san = new SubjectAlternativeName(sanitizedLogicals.map((logical) => new GeneralName({
25772
- uniformResourceIdentifier: `${LOGICAL_URI_PREFIX}${logical}`,
25773
- })));
25774
- const extensions = new Extensions([
25775
- new Extension({
25776
- extnID: id_ce_subjectAltName,
25777
- critical: false,
25778
- extnValue: new OctetString(AsnConvert.serialize(san)),
25779
- }),
25780
- ]);
25781
- attributes.push(new Attribute({
25782
- type: EXTENSION_REQUEST_OID,
25783
- values: [AsnConvert.serialize(extensions)],
25784
- }));
25785
- }
25786
- const requestInfo = new CertificationRequestInfo({
25787
- subject,
25788
- subjectPKInfo: subjectPkInfo,
25789
- attributes,
25790
- });
25791
- const requestInfoDer = AsnConvert.serialize(requestInfo);
25792
- const signature = await cryptoImpl.subtle.sign('Ed25519', privateKey, requestInfoDer);
25793
- const certificationRequest = new CertificationRequest({
25794
- certificationRequestInfo: requestInfo,
25795
- signatureAlgorithm: new AlgorithmIdentifier({
25796
- algorithm: ED25519_OID,
25797
- }),
25798
- signature: encodeBitString(signature),
25799
- });
25800
- certificationRequest.certificationRequestInfoRaw = requestInfoDer;
25801
- const csrDer = AsnConvert.serialize(certificationRequest);
25802
- const csrPem = arrayBufferToPem(csrDer, CSR_PEM_TAG);
25803
- logger$v.debug('csr_created', {
25804
- node_id: trimmedNodeId,
25805
- physical_path: trimmedPhysicalPath,
25806
- logical_count: sanitizedLogicals.length,
25807
- });
25808
- return csrPem;
25809
- }
25810
- catch (error) {
25811
- logger$v.error('csr_creation_failed', {
25812
- node_id: trimmedNodeId,
25813
- physical_path: trimmedPhysicalPath,
25814
- error: error instanceof Error ? error.message : String(error),
25815
- });
25816
- throw error;
25817
- }
25818
- }
25819
25797
  }
25820
25798
  async function buildProviderArtifacts(options) {
25821
25799
  const algorithm = normalizeAlgorithm(options.algorithm ?? readEnvAlgorithm());
@@ -26051,90 +26029,6 @@ function pemToDerBase64(pem) {
26051
26029
  // Ensure the output is valid base64 without whitespace
26052
26030
  return base64.replace(/\s+/g, '');
26053
26031
  }
26054
- let cryptoPromise = null;
26055
- async function ensureWebCrypto() {
26056
- if (typeof globalThis.crypto !== 'undefined' && globalThis.crypto?.subtle) {
26057
- return globalThis.crypto;
26058
- }
26059
- if (!cryptoPromise) {
26060
- if (typeof process !== 'undefined' &&
26061
- typeof process.versions?.node === 'string') {
26062
- cryptoPromise = import('node:crypto').then((module) => {
26063
- const webcrypto = module.webcrypto;
26064
- if (!webcrypto || !webcrypto.subtle) {
26065
- throw new Error('WebCrypto API is not available in this Node.js runtime');
26066
- }
26067
- globalThis.crypto = webcrypto;
26068
- return webcrypto;
26069
- });
26070
- }
26071
- else {
26072
- cryptoPromise = Promise.reject(new Error('WebCrypto API is not available in this environment'));
26073
- }
26074
- }
26075
- return cryptoPromise;
26076
- }
26077
- function pemToArrayBuffer(pem) {
26078
- const normalized = pem
26079
- .replace(/-----BEGIN[^-]+-----/g, '')
26080
- .replace(/-----END[^-]+-----/g, '')
26081
- .replace(/\s+/g, '');
26082
- const bytes = base64ToBytes$1(normalized);
26083
- return bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength);
26084
- }
26085
- function base64ToBytes$1(base64) {
26086
- if (typeof Buffer !== 'undefined') {
26087
- const buffer = Buffer.from(base64, 'base64');
26088
- const bytes = new Uint8Array(buffer.length);
26089
- for (let i = 0; i < buffer.length; i += 1) {
26090
- bytes[i] = buffer[i];
26091
- }
26092
- return bytes;
26093
- }
26094
- if (typeof atob === 'function') {
26095
- const binary = atob(base64);
26096
- const bytes = new Uint8Array(binary.length);
26097
- for (let i = 0; i < binary.length; i += 1) {
26098
- bytes[i] = binary.charCodeAt(i);
26099
- }
26100
- return bytes;
26101
- }
26102
- throw new Error('No base64 decoder available in this environment');
26103
- }
26104
- function arrayBufferToPem(buffer, tag) {
26105
- const base64 = bytesToBase64(new Uint8Array(buffer));
26106
- return `-----BEGIN ${tag}-----\n${formatPem(base64)}\n-----END ${tag}-----\n`;
26107
- }
26108
- function formatPem(base64) {
26109
- const lines = [];
26110
- for (let i = 0; i < base64.length; i += 64) {
26111
- lines.push(base64.slice(i, i + 64));
26112
- }
26113
- return lines.join('\n');
26114
- }
26115
- function encodeBitString(signature) {
26116
- const bytes = new Uint8Array(signature);
26117
- const bitString = new Uint8Array(bytes.length + 1);
26118
- bitString.set(bytes, 1);
26119
- return bitString.buffer;
26120
- }
26121
- function buildSubjectName(commonName) {
26122
- const attribute = new AttributeTypeAndValue({
26123
- type: COMMON_NAME_OID,
26124
- value: new AttributeValue({ utf8String: commonName }),
26125
- });
26126
- return new Name([new RelativeDistinguishedName([attribute])]);
26127
- }
26128
- function assertNonEmptyString(value, name) {
26129
- if (typeof value !== 'string') {
26130
- throw new TypeError(`${name} must be a string`);
26131
- }
26132
- const trimmed = value.trim();
26133
- if (trimmed.length === 0) {
26134
- throw new TypeError(`${name} must be a non-empty string`);
26135
- }
26136
- return trimmed;
26137
- }
26138
26032
  function cloneJson(value) {
26139
26033
  return JSON.parse(JSON.stringify(value));
26140
26034
  }
@@ -31776,6 +31670,8 @@ const ENV_VAR_DIRECT_INPAGE_CHANNEL = 'FAME_DIRECT_INPAGE_CHANNEL';
31776
31670
  const ENV_VAR_ADMISSION_SERVICE_URL = 'FAME_ADMISSION_SERVICE_URL';
31777
31671
  const DEFAULT_INPAGE_CHANNEL = 'naylence-fabric';
31778
31672
  const PROFILE_NAME_WELCOME = 'welcome';
31673
+ const PROFILE_NAME_WELCOME_PKCE = 'welcome-pkce';
31674
+ const PROFILE_NAME_WELCOME_PKCE_ALIAS = 'welcome_pkce';
31779
31675
  const PROFILE_NAME_DIRECT = 'direct';
31780
31676
  const PROFILE_NAME_DIRECT_HTTP = 'direct-http';
31781
31677
  const PROFILE_NAME_DIRECT_INPAGE = 'direct-inpage';
@@ -31836,6 +31732,7 @@ function createOAuthPkceTokenProviderConfig() {
31836
31732
  }
31837
31733
  const welcomeIsRoot = Expressions.env(ENV_VAR_IS_ROOT, 'false');
31838
31734
  const welcomeTokenProvider = createOAuthTokenProviderConfig();
31735
+ const welcomePkceTokenProvider = createOAuthPkceTokenProviderConfig();
31839
31736
  const WELCOME_SERVICE_PROFILE = {
31840
31737
  type: 'WelcomeServiceClient',
31841
31738
  is_root: welcomeIsRoot,
@@ -31849,6 +31746,19 @@ const WELCOME_SERVICE_PROFILE = {
31849
31746
  tokenProvider: welcomeTokenProvider,
31850
31747
  },
31851
31748
  };
31749
+ const WELCOME_SERVICE_PKCE_PROFILE = {
31750
+ type: 'WelcomeServiceClient',
31751
+ is_root: welcomeIsRoot,
31752
+ isRoot: welcomeIsRoot,
31753
+ url: Expressions.env(ENV_VAR_ADMISSION_SERVICE_URL),
31754
+ supported_transports: ['websocket'],
31755
+ supportedTransports: ['websocket'],
31756
+ auth: {
31757
+ type: 'BearerTokenHeaderAuth',
31758
+ token_provider: welcomePkceTokenProvider,
31759
+ tokenProvider: welcomePkceTokenProvider,
31760
+ },
31761
+ };
31852
31762
  const directGrantTokenProvider = createOAuthTokenProviderConfig();
31853
31763
  const directGrant = {
31854
31764
  type: 'WebSocketConnectionGrant',
@@ -31954,6 +31864,8 @@ const NOOP_PROFILE = {
31954
31864
  };
31955
31865
  const PROFILE_MAP$1 = {
31956
31866
  [PROFILE_NAME_WELCOME]: WELCOME_SERVICE_PROFILE,
31867
+ [PROFILE_NAME_WELCOME_PKCE]: WELCOME_SERVICE_PKCE_PROFILE,
31868
+ [PROFILE_NAME_WELCOME_PKCE_ALIAS]: WELCOME_SERVICE_PKCE_PROFILE,
31957
31869
  [PROFILE_NAME_DIRECT]: DIRECT_PROFILE,
31958
31870
  [PROFILE_NAME_DIRECT_PKCE]: DIRECT_PKCE_PROFILE,
31959
31871
  [PROFILE_NAME_DIRECT_PKCE_ALIAS]: DIRECT_PKCE_PROFILE,