@naylence/runtime 0.3.5-test.911 → 0.3.5-test.913
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/dist/browser/index.cjs +72 -164
- package/dist/browser/index.mjs +72 -164
- package/dist/cjs/naylence/fame/config/extended-fame-config.js +52 -0
- package/dist/cjs/naylence/fame/http/jwks-api-router.js +16 -18
- package/dist/cjs/naylence/fame/http/oauth2-server.js +28 -31
- package/dist/cjs/naylence/fame/http/oauth2-token-router.js +153 -8
- package/dist/cjs/naylence/fame/http/openid-configuration-router.js +30 -32
- package/dist/cjs/naylence/fame/node/admission/admission-profile-factory.js +18 -0
- package/dist/cjs/naylence/fame/security/crypto/providers/default-crypto-provider.js +0 -162
- package/dist/cjs/version.js +2 -2
- package/dist/esm/naylence/fame/config/extended-fame-config.js +52 -0
- package/dist/esm/naylence/fame/http/jwks-api-router.js +16 -17
- package/dist/esm/naylence/fame/http/oauth2-server.js +28 -31
- package/dist/esm/naylence/fame/http/oauth2-token-router.js +153 -8
- package/dist/esm/naylence/fame/http/openid-configuration-router.js +30 -31
- package/dist/esm/naylence/fame/node/admission/admission-profile-factory.js +18 -0
- package/dist/esm/naylence/fame/security/crypto/providers/default-crypto-provider.js +0 -162
- package/dist/esm/version.js +2 -2
- package/dist/node/index.cjs +72 -164
- package/dist/node/index.mjs +72 -164
- package/dist/node/node.cjs +299 -249
- package/dist/node/node.mjs +299 -249
- package/dist/types/naylence/fame/http/jwks-api-router.d.ts +8 -8
- package/dist/types/naylence/fame/http/oauth2-server.d.ts +3 -3
- package/dist/types/naylence/fame/http/oauth2-token-router.d.ts +5 -5
- package/dist/types/naylence/fame/http/openid-configuration-router.d.ts +8 -8
- package/dist/types/naylence/fame/security/crypto/providers/default-crypto-provider.d.ts +0 -1
- package/dist/types/version.d.ts +1 -1
- package/package.json +4 -6
- package/dist/esm/naylence/fame/fastapi/oauth2-server.js +0 -205
- package/dist/types/naylence/fame/fastapi/oauth2-server.d.ts +0 -22
package/dist/browser/index.cjs
CHANGED
|
@@ -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.
|
|
101
|
+
// Generated from package.json version: 0.3.5-test.913
|
|
105
102
|
/**
|
|
106
103
|
* The package version, injected at build time.
|
|
107
104
|
* @internal
|
|
108
105
|
*/
|
|
109
|
-
const VERSION = '0.3.5-test.
|
|
106
|
+
const VERSION = '0.3.5-test.913';
|
|
110
107
|
|
|
111
108
|
/**
|
|
112
109
|
* Fame protocol specific error classes with WebSocket close codes and proper inheritance.
|
|
@@ -13093,6 +13090,57 @@ 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
|
+
// Shared flag that allows synchronous waiting for the Node-specific require shim
|
|
13103
|
+
const requireReadyFlag = isNode && typeof SharedArrayBuffer !== 'undefined'
|
|
13104
|
+
? new Int32Array(new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT))
|
|
13105
|
+
: null;
|
|
13106
|
+
if (requireReadyFlag) {
|
|
13107
|
+
// 0 means initializing, 1 means ready (success or failure)
|
|
13108
|
+
Atomics.store(requireReadyFlag, 0, 0);
|
|
13109
|
+
// Prepare a CommonJS-style require when running in pure ESM contexts
|
|
13110
|
+
void (async () => {
|
|
13111
|
+
try {
|
|
13112
|
+
if (typeof require !== 'function') {
|
|
13113
|
+
const moduleNamespace = (await import('node:module'));
|
|
13114
|
+
const createRequire = moduleNamespace.createRequire;
|
|
13115
|
+
if (typeof createRequire === 'function') {
|
|
13116
|
+
const fallbackPath = `${process.cwd()}/.__naylence_require_shim__.mjs`;
|
|
13117
|
+
const nodeRequire = createRequire(currentModuleUrl ?? fallbackPath);
|
|
13118
|
+
globalThis.require = nodeRequire;
|
|
13119
|
+
}
|
|
13120
|
+
}
|
|
13121
|
+
}
|
|
13122
|
+
catch {
|
|
13123
|
+
// Ignore failures – getFsModule will surface a helpful error when needed
|
|
13124
|
+
}
|
|
13125
|
+
})()
|
|
13126
|
+
.catch(() => {
|
|
13127
|
+
// Ignore async errors – the ready flag will still unblock consumers
|
|
13128
|
+
})
|
|
13129
|
+
.finally(() => {
|
|
13130
|
+
Atomics.store(requireReadyFlag, 0, 1);
|
|
13131
|
+
Atomics.notify(requireReadyFlag, 0);
|
|
13132
|
+
});
|
|
13133
|
+
}
|
|
13134
|
+
function ensureRequireReady() {
|
|
13135
|
+
if (!requireReadyFlag) {
|
|
13136
|
+
return;
|
|
13137
|
+
}
|
|
13138
|
+
if (Atomics.load(requireReadyFlag, 0) === 1) {
|
|
13139
|
+
return;
|
|
13140
|
+
}
|
|
13141
|
+
// Block until the asynchronous loader finishes initialising
|
|
13142
|
+
Atomics.wait(requireReadyFlag, 0, 0);
|
|
13143
|
+
}
|
|
13096
13144
|
function getFsModule() {
|
|
13097
13145
|
if (cachedFsModule) {
|
|
13098
13146
|
return cachedFsModule;
|
|
@@ -13100,6 +13148,7 @@ function getFsModule() {
|
|
|
13100
13148
|
if (!isNode) {
|
|
13101
13149
|
throw new Error('File system access is not available in this environment');
|
|
13102
13150
|
}
|
|
13151
|
+
ensureRequireReady();
|
|
13103
13152
|
if (typeof require === 'function') {
|
|
13104
13153
|
try {
|
|
13105
13154
|
cachedFsModule = require(fsModuleSpecifier);
|
|
@@ -25478,11 +25527,6 @@ const DEFAULT_AUDIENCE = 'router-dev';
|
|
|
25478
25527
|
const DEFAULT_TTL_SEC$1 = 3600;
|
|
25479
25528
|
const DEFAULT_HMAC_SECRET_BYTES = 32;
|
|
25480
25529
|
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
25530
|
function normalizeDefaultCryptoProviderOptions(options) {
|
|
25487
25531
|
if (!options) {
|
|
25488
25532
|
return {};
|
|
@@ -25748,76 +25792,6 @@ class DefaultCryptoProvider {
|
|
|
25748
25792
|
has_chain: Boolean(certificateChainPem),
|
|
25749
25793
|
});
|
|
25750
25794
|
}
|
|
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
25795
|
}
|
|
25822
25796
|
async function buildProviderArtifacts(options) {
|
|
25823
25797
|
const algorithm = normalizeAlgorithm(options.algorithm ?? readEnvAlgorithm());
|
|
@@ -26053,90 +26027,6 @@ function pemToDerBase64(pem) {
|
|
|
26053
26027
|
// Ensure the output is valid base64 without whitespace
|
|
26054
26028
|
return base64.replace(/\s+/g, '');
|
|
26055
26029
|
}
|
|
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
26030
|
function cloneJson(value) {
|
|
26141
26031
|
return JSON.parse(JSON.stringify(value));
|
|
26142
26032
|
}
|
|
@@ -31778,6 +31668,8 @@ const ENV_VAR_DIRECT_INPAGE_CHANNEL = 'FAME_DIRECT_INPAGE_CHANNEL';
|
|
|
31778
31668
|
const ENV_VAR_ADMISSION_SERVICE_URL = 'FAME_ADMISSION_SERVICE_URL';
|
|
31779
31669
|
const DEFAULT_INPAGE_CHANNEL = 'naylence-fabric';
|
|
31780
31670
|
const PROFILE_NAME_WELCOME = 'welcome';
|
|
31671
|
+
const PROFILE_NAME_WELCOME_PKCE = 'welcome-pkce';
|
|
31672
|
+
const PROFILE_NAME_WELCOME_PKCE_ALIAS = 'welcome_pkce';
|
|
31781
31673
|
const PROFILE_NAME_DIRECT = 'direct';
|
|
31782
31674
|
const PROFILE_NAME_DIRECT_HTTP = 'direct-http';
|
|
31783
31675
|
const PROFILE_NAME_DIRECT_INPAGE = 'direct-inpage';
|
|
@@ -31838,6 +31730,7 @@ function createOAuthPkceTokenProviderConfig() {
|
|
|
31838
31730
|
}
|
|
31839
31731
|
const welcomeIsRoot = factory.Expressions.env(ENV_VAR_IS_ROOT, 'false');
|
|
31840
31732
|
const welcomeTokenProvider = createOAuthTokenProviderConfig();
|
|
31733
|
+
const welcomePkceTokenProvider = createOAuthPkceTokenProviderConfig();
|
|
31841
31734
|
const WELCOME_SERVICE_PROFILE = {
|
|
31842
31735
|
type: 'WelcomeServiceClient',
|
|
31843
31736
|
is_root: welcomeIsRoot,
|
|
@@ -31851,6 +31744,19 @@ const WELCOME_SERVICE_PROFILE = {
|
|
|
31851
31744
|
tokenProvider: welcomeTokenProvider,
|
|
31852
31745
|
},
|
|
31853
31746
|
};
|
|
31747
|
+
const WELCOME_SERVICE_PKCE_PROFILE = {
|
|
31748
|
+
type: 'WelcomeServiceClient',
|
|
31749
|
+
is_root: welcomeIsRoot,
|
|
31750
|
+
isRoot: welcomeIsRoot,
|
|
31751
|
+
url: factory.Expressions.env(ENV_VAR_ADMISSION_SERVICE_URL),
|
|
31752
|
+
supported_transports: ['websocket'],
|
|
31753
|
+
supportedTransports: ['websocket'],
|
|
31754
|
+
auth: {
|
|
31755
|
+
type: 'BearerTokenHeaderAuth',
|
|
31756
|
+
token_provider: welcomePkceTokenProvider,
|
|
31757
|
+
tokenProvider: welcomePkceTokenProvider,
|
|
31758
|
+
},
|
|
31759
|
+
};
|
|
31854
31760
|
const directGrantTokenProvider = createOAuthTokenProviderConfig();
|
|
31855
31761
|
const directGrant = {
|
|
31856
31762
|
type: 'WebSocketConnectionGrant',
|
|
@@ -31956,6 +31862,8 @@ const NOOP_PROFILE = {
|
|
|
31956
31862
|
};
|
|
31957
31863
|
const PROFILE_MAP$1 = {
|
|
31958
31864
|
[PROFILE_NAME_WELCOME]: WELCOME_SERVICE_PROFILE,
|
|
31865
|
+
[PROFILE_NAME_WELCOME_PKCE]: WELCOME_SERVICE_PKCE_PROFILE,
|
|
31866
|
+
[PROFILE_NAME_WELCOME_PKCE_ALIAS]: WELCOME_SERVICE_PKCE_PROFILE,
|
|
31959
31867
|
[PROFILE_NAME_DIRECT]: DIRECT_PROFILE,
|
|
31960
31868
|
[PROFILE_NAME_DIRECT_PKCE]: DIRECT_PKCE_PROFILE,
|
|
31961
31869
|
[PROFILE_NAME_DIRECT_PKCE_ALIAS]: DIRECT_PKCE_PROFILE,
|
package/dist/browser/index.mjs
CHANGED
|
@@ -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.
|
|
99
|
+
// Generated from package.json version: 0.3.5-test.913
|
|
103
100
|
/**
|
|
104
101
|
* The package version, injected at build time.
|
|
105
102
|
* @internal
|
|
106
103
|
*/
|
|
107
|
-
const VERSION = '0.3.5-test.
|
|
104
|
+
const VERSION = '0.3.5-test.913';
|
|
108
105
|
|
|
109
106
|
/**
|
|
110
107
|
* Fame protocol specific error classes with WebSocket close codes and proper inheritance.
|
|
@@ -13091,6 +13088,57 @@ 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
|
+
// Shared flag that allows synchronous waiting for the Node-specific require shim
|
|
13101
|
+
const requireReadyFlag = isNode && typeof SharedArrayBuffer !== 'undefined'
|
|
13102
|
+
? new Int32Array(new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT))
|
|
13103
|
+
: null;
|
|
13104
|
+
if (requireReadyFlag) {
|
|
13105
|
+
// 0 means initializing, 1 means ready (success or failure)
|
|
13106
|
+
Atomics.store(requireReadyFlag, 0, 0);
|
|
13107
|
+
// Prepare a CommonJS-style require when running in pure ESM contexts
|
|
13108
|
+
void (async () => {
|
|
13109
|
+
try {
|
|
13110
|
+
if (typeof require !== 'function') {
|
|
13111
|
+
const moduleNamespace = (await import('node:module'));
|
|
13112
|
+
const createRequire = moduleNamespace.createRequire;
|
|
13113
|
+
if (typeof createRequire === 'function') {
|
|
13114
|
+
const fallbackPath = `${process.cwd()}/.__naylence_require_shim__.mjs`;
|
|
13115
|
+
const nodeRequire = createRequire(currentModuleUrl ?? fallbackPath);
|
|
13116
|
+
globalThis.require = nodeRequire;
|
|
13117
|
+
}
|
|
13118
|
+
}
|
|
13119
|
+
}
|
|
13120
|
+
catch {
|
|
13121
|
+
// Ignore failures – getFsModule will surface a helpful error when needed
|
|
13122
|
+
}
|
|
13123
|
+
})()
|
|
13124
|
+
.catch(() => {
|
|
13125
|
+
// Ignore async errors – the ready flag will still unblock consumers
|
|
13126
|
+
})
|
|
13127
|
+
.finally(() => {
|
|
13128
|
+
Atomics.store(requireReadyFlag, 0, 1);
|
|
13129
|
+
Atomics.notify(requireReadyFlag, 0);
|
|
13130
|
+
});
|
|
13131
|
+
}
|
|
13132
|
+
function ensureRequireReady() {
|
|
13133
|
+
if (!requireReadyFlag) {
|
|
13134
|
+
return;
|
|
13135
|
+
}
|
|
13136
|
+
if (Atomics.load(requireReadyFlag, 0) === 1) {
|
|
13137
|
+
return;
|
|
13138
|
+
}
|
|
13139
|
+
// Block until the asynchronous loader finishes initialising
|
|
13140
|
+
Atomics.wait(requireReadyFlag, 0, 0);
|
|
13141
|
+
}
|
|
13094
13142
|
function getFsModule() {
|
|
13095
13143
|
if (cachedFsModule) {
|
|
13096
13144
|
return cachedFsModule;
|
|
@@ -13098,6 +13146,7 @@ function getFsModule() {
|
|
|
13098
13146
|
if (!isNode) {
|
|
13099
13147
|
throw new Error('File system access is not available in this environment');
|
|
13100
13148
|
}
|
|
13149
|
+
ensureRequireReady();
|
|
13101
13150
|
if (typeof require === 'function') {
|
|
13102
13151
|
try {
|
|
13103
13152
|
cachedFsModule = require(fsModuleSpecifier);
|
|
@@ -25476,11 +25525,6 @@ const DEFAULT_AUDIENCE = 'router-dev';
|
|
|
25476
25525
|
const DEFAULT_TTL_SEC$1 = 3600;
|
|
25477
25526
|
const DEFAULT_HMAC_SECRET_BYTES = 32;
|
|
25478
25527
|
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
25528
|
function normalizeDefaultCryptoProviderOptions(options) {
|
|
25485
25529
|
if (!options) {
|
|
25486
25530
|
return {};
|
|
@@ -25746,76 +25790,6 @@ class DefaultCryptoProvider {
|
|
|
25746
25790
|
has_chain: Boolean(certificateChainPem),
|
|
25747
25791
|
});
|
|
25748
25792
|
}
|
|
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
25793
|
}
|
|
25820
25794
|
async function buildProviderArtifacts(options) {
|
|
25821
25795
|
const algorithm = normalizeAlgorithm(options.algorithm ?? readEnvAlgorithm());
|
|
@@ -26051,90 +26025,6 @@ function pemToDerBase64(pem) {
|
|
|
26051
26025
|
// Ensure the output is valid base64 without whitespace
|
|
26052
26026
|
return base64.replace(/\s+/g, '');
|
|
26053
26027
|
}
|
|
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
26028
|
function cloneJson(value) {
|
|
26139
26029
|
return JSON.parse(JSON.stringify(value));
|
|
26140
26030
|
}
|
|
@@ -31776,6 +31666,8 @@ const ENV_VAR_DIRECT_INPAGE_CHANNEL = 'FAME_DIRECT_INPAGE_CHANNEL';
|
|
|
31776
31666
|
const ENV_VAR_ADMISSION_SERVICE_URL = 'FAME_ADMISSION_SERVICE_URL';
|
|
31777
31667
|
const DEFAULT_INPAGE_CHANNEL = 'naylence-fabric';
|
|
31778
31668
|
const PROFILE_NAME_WELCOME = 'welcome';
|
|
31669
|
+
const PROFILE_NAME_WELCOME_PKCE = 'welcome-pkce';
|
|
31670
|
+
const PROFILE_NAME_WELCOME_PKCE_ALIAS = 'welcome_pkce';
|
|
31779
31671
|
const PROFILE_NAME_DIRECT = 'direct';
|
|
31780
31672
|
const PROFILE_NAME_DIRECT_HTTP = 'direct-http';
|
|
31781
31673
|
const PROFILE_NAME_DIRECT_INPAGE = 'direct-inpage';
|
|
@@ -31836,6 +31728,7 @@ function createOAuthPkceTokenProviderConfig() {
|
|
|
31836
31728
|
}
|
|
31837
31729
|
const welcomeIsRoot = Expressions.env(ENV_VAR_IS_ROOT, 'false');
|
|
31838
31730
|
const welcomeTokenProvider = createOAuthTokenProviderConfig();
|
|
31731
|
+
const welcomePkceTokenProvider = createOAuthPkceTokenProviderConfig();
|
|
31839
31732
|
const WELCOME_SERVICE_PROFILE = {
|
|
31840
31733
|
type: 'WelcomeServiceClient',
|
|
31841
31734
|
is_root: welcomeIsRoot,
|
|
@@ -31849,6 +31742,19 @@ const WELCOME_SERVICE_PROFILE = {
|
|
|
31849
31742
|
tokenProvider: welcomeTokenProvider,
|
|
31850
31743
|
},
|
|
31851
31744
|
};
|
|
31745
|
+
const WELCOME_SERVICE_PKCE_PROFILE = {
|
|
31746
|
+
type: 'WelcomeServiceClient',
|
|
31747
|
+
is_root: welcomeIsRoot,
|
|
31748
|
+
isRoot: welcomeIsRoot,
|
|
31749
|
+
url: Expressions.env(ENV_VAR_ADMISSION_SERVICE_URL),
|
|
31750
|
+
supported_transports: ['websocket'],
|
|
31751
|
+
supportedTransports: ['websocket'],
|
|
31752
|
+
auth: {
|
|
31753
|
+
type: 'BearerTokenHeaderAuth',
|
|
31754
|
+
token_provider: welcomePkceTokenProvider,
|
|
31755
|
+
tokenProvider: welcomePkceTokenProvider,
|
|
31756
|
+
},
|
|
31757
|
+
};
|
|
31852
31758
|
const directGrantTokenProvider = createOAuthTokenProviderConfig();
|
|
31853
31759
|
const directGrant = {
|
|
31854
31760
|
type: 'WebSocketConnectionGrant',
|
|
@@ -31954,6 +31860,8 @@ const NOOP_PROFILE = {
|
|
|
31954
31860
|
};
|
|
31955
31861
|
const PROFILE_MAP$1 = {
|
|
31956
31862
|
[PROFILE_NAME_WELCOME]: WELCOME_SERVICE_PROFILE,
|
|
31863
|
+
[PROFILE_NAME_WELCOME_PKCE]: WELCOME_SERVICE_PKCE_PROFILE,
|
|
31864
|
+
[PROFILE_NAME_WELCOME_PKCE_ALIAS]: WELCOME_SERVICE_PKCE_PROFILE,
|
|
31957
31865
|
[PROFILE_NAME_DIRECT]: DIRECT_PROFILE,
|
|
31958
31866
|
[PROFILE_NAME_DIRECT_PKCE]: DIRECT_PKCE_PROFILE,
|
|
31959
31867
|
[PROFILE_NAME_DIRECT_PKCE_ALIAS]: DIRECT_PKCE_PROFILE,
|
|
@@ -57,6 +57,57 @@ const CONFIG_SEARCH_PATHS = [
|
|
|
57
57
|
];
|
|
58
58
|
const fsModuleSpecifier = String.fromCharCode(102) + String.fromCharCode(115);
|
|
59
59
|
let cachedFsModule = null;
|
|
60
|
+
// Capture this module's URL without triggering TypeScript's import.meta restriction on CJS builds
|
|
61
|
+
const currentModuleUrl = (() => {
|
|
62
|
+
try {
|
|
63
|
+
return (0, eval)('import.meta.url');
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
return undefined;
|
|
67
|
+
}
|
|
68
|
+
})();
|
|
69
|
+
// Shared flag that allows synchronous waiting for the Node-specific require shim
|
|
70
|
+
const requireReadyFlag = logging_types_js_1.isNode && typeof SharedArrayBuffer !== 'undefined'
|
|
71
|
+
? new Int32Array(new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT))
|
|
72
|
+
: null;
|
|
73
|
+
if (requireReadyFlag) {
|
|
74
|
+
// 0 means initializing, 1 means ready (success or failure)
|
|
75
|
+
Atomics.store(requireReadyFlag, 0, 0);
|
|
76
|
+
// Prepare a CommonJS-style require when running in pure ESM contexts
|
|
77
|
+
void (async () => {
|
|
78
|
+
try {
|
|
79
|
+
if (typeof require !== 'function') {
|
|
80
|
+
const moduleNamespace = (await Promise.resolve().then(() => __importStar(require('node:module'))));
|
|
81
|
+
const createRequire = moduleNamespace.createRequire;
|
|
82
|
+
if (typeof createRequire === 'function') {
|
|
83
|
+
const fallbackPath = `${process.cwd()}/.__naylence_require_shim__.mjs`;
|
|
84
|
+
const nodeRequire = createRequire(currentModuleUrl ?? fallbackPath);
|
|
85
|
+
globalThis.require = nodeRequire;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
// Ignore failures – getFsModule will surface a helpful error when needed
|
|
91
|
+
}
|
|
92
|
+
})()
|
|
93
|
+
.catch(() => {
|
|
94
|
+
// Ignore async errors – the ready flag will still unblock consumers
|
|
95
|
+
})
|
|
96
|
+
.finally(() => {
|
|
97
|
+
Atomics.store(requireReadyFlag, 0, 1);
|
|
98
|
+
Atomics.notify(requireReadyFlag, 0);
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
function ensureRequireReady() {
|
|
102
|
+
if (!requireReadyFlag) {
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
if (Atomics.load(requireReadyFlag, 0) === 1) {
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
// Block until the asynchronous loader finishes initialising
|
|
109
|
+
Atomics.wait(requireReadyFlag, 0, 0);
|
|
110
|
+
}
|
|
60
111
|
function getFsModule() {
|
|
61
112
|
if (cachedFsModule) {
|
|
62
113
|
return cachedFsModule;
|
|
@@ -64,6 +115,7 @@ function getFsModule() {
|
|
|
64
115
|
if (!logging_types_js_1.isNode) {
|
|
65
116
|
throw new Error('File system access is not available in this environment');
|
|
66
117
|
}
|
|
118
|
+
ensureRequireReady();
|
|
67
119
|
if (typeof require === 'function') {
|
|
68
120
|
try {
|
|
69
121
|
cachedFsModule = require(fsModuleSpecifier);
|