@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/node/index.mjs
CHANGED
|
@@ -7,21 +7,18 @@ 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';
|
|
16
13
|
import { sign, hashes, verify } from '@noble/ed25519';
|
|
17
14
|
|
|
18
15
|
// This file is auto-generated during build - do not edit manually
|
|
19
|
-
// Generated from package.json version: 0.3.5-test.
|
|
16
|
+
// Generated from package.json version: 0.3.5-test.913
|
|
20
17
|
/**
|
|
21
18
|
* The package version, injected at build time.
|
|
22
19
|
* @internal
|
|
23
20
|
*/
|
|
24
|
-
const VERSION = '0.3.5-test.
|
|
21
|
+
const VERSION = '0.3.5-test.913';
|
|
25
22
|
|
|
26
23
|
/**
|
|
27
24
|
* Fame protocol specific error classes with WebSocket close codes and proper inheritance.
|
|
@@ -13008,6 +13005,57 @@ const CONFIG_SEARCH_PATHS = [
|
|
|
13008
13005
|
];
|
|
13009
13006
|
const fsModuleSpecifier = String.fromCharCode(102) + String.fromCharCode(115);
|
|
13010
13007
|
let cachedFsModule = null;
|
|
13008
|
+
// Capture this module's URL without triggering TypeScript's import.meta restriction on CJS builds
|
|
13009
|
+
const currentModuleUrl = (() => {
|
|
13010
|
+
try {
|
|
13011
|
+
return (0, eval)('import.meta.url');
|
|
13012
|
+
}
|
|
13013
|
+
catch {
|
|
13014
|
+
return undefined;
|
|
13015
|
+
}
|
|
13016
|
+
})();
|
|
13017
|
+
// Shared flag that allows synchronous waiting for the Node-specific require shim
|
|
13018
|
+
const requireReadyFlag = isNode && typeof SharedArrayBuffer !== 'undefined'
|
|
13019
|
+
? new Int32Array(new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT))
|
|
13020
|
+
: null;
|
|
13021
|
+
if (requireReadyFlag) {
|
|
13022
|
+
// 0 means initializing, 1 means ready (success or failure)
|
|
13023
|
+
Atomics.store(requireReadyFlag, 0, 0);
|
|
13024
|
+
// Prepare a CommonJS-style require when running in pure ESM contexts
|
|
13025
|
+
void (async () => {
|
|
13026
|
+
try {
|
|
13027
|
+
if (typeof require !== 'function') {
|
|
13028
|
+
const moduleNamespace = (await import('node:module'));
|
|
13029
|
+
const createRequire = moduleNamespace.createRequire;
|
|
13030
|
+
if (typeof createRequire === 'function') {
|
|
13031
|
+
const fallbackPath = `${process.cwd()}/.__naylence_require_shim__.mjs`;
|
|
13032
|
+
const nodeRequire = createRequire(currentModuleUrl ?? fallbackPath);
|
|
13033
|
+
globalThis.require = nodeRequire;
|
|
13034
|
+
}
|
|
13035
|
+
}
|
|
13036
|
+
}
|
|
13037
|
+
catch {
|
|
13038
|
+
// Ignore failures – getFsModule will surface a helpful error when needed
|
|
13039
|
+
}
|
|
13040
|
+
})()
|
|
13041
|
+
.catch(() => {
|
|
13042
|
+
// Ignore async errors – the ready flag will still unblock consumers
|
|
13043
|
+
})
|
|
13044
|
+
.finally(() => {
|
|
13045
|
+
Atomics.store(requireReadyFlag, 0, 1);
|
|
13046
|
+
Atomics.notify(requireReadyFlag, 0);
|
|
13047
|
+
});
|
|
13048
|
+
}
|
|
13049
|
+
function ensureRequireReady() {
|
|
13050
|
+
if (!requireReadyFlag) {
|
|
13051
|
+
return;
|
|
13052
|
+
}
|
|
13053
|
+
if (Atomics.load(requireReadyFlag, 0) === 1) {
|
|
13054
|
+
return;
|
|
13055
|
+
}
|
|
13056
|
+
// Block until the asynchronous loader finishes initialising
|
|
13057
|
+
Atomics.wait(requireReadyFlag, 0, 0);
|
|
13058
|
+
}
|
|
13011
13059
|
function getFsModule() {
|
|
13012
13060
|
if (cachedFsModule) {
|
|
13013
13061
|
return cachedFsModule;
|
|
@@ -13015,6 +13063,7 @@ function getFsModule() {
|
|
|
13015
13063
|
if (!isNode) {
|
|
13016
13064
|
throw new Error('File system access is not available in this environment');
|
|
13017
13065
|
}
|
|
13066
|
+
ensureRequireReady();
|
|
13018
13067
|
if (typeof require === 'function') {
|
|
13019
13068
|
try {
|
|
13020
13069
|
cachedFsModule = require(fsModuleSpecifier);
|
|
@@ -25393,11 +25442,6 @@ const DEFAULT_AUDIENCE = 'router-dev';
|
|
|
25393
25442
|
const DEFAULT_TTL_SEC$1 = 3600;
|
|
25394
25443
|
const DEFAULT_HMAC_SECRET_BYTES = 32;
|
|
25395
25444
|
const ENCRYPTION_ALG = 'ECDH-ES';
|
|
25396
|
-
const EXTENSION_REQUEST_OID = '1.2.840.113549.1.9.14';
|
|
25397
|
-
const COMMON_NAME_OID = '2.5.4.3';
|
|
25398
|
-
const ED25519_OID = '1.3.101.112';
|
|
25399
|
-
const CSR_PEM_TAG = 'CERTIFICATE REQUEST';
|
|
25400
|
-
const LOGICAL_URI_PREFIX = 'naylence://';
|
|
25401
25445
|
function normalizeDefaultCryptoProviderOptions(options) {
|
|
25402
25446
|
if (!options) {
|
|
25403
25447
|
return {};
|
|
@@ -25663,76 +25707,6 @@ class DefaultCryptoProvider {
|
|
|
25663
25707
|
has_chain: Boolean(certificateChainPem),
|
|
25664
25708
|
});
|
|
25665
25709
|
}
|
|
25666
|
-
async createCsr(nodeId, physicalPath, logicals, subjectName) {
|
|
25667
|
-
const trimmedNodeId = assertNonEmptyString(nodeId, 'nodeId');
|
|
25668
|
-
const trimmedPhysicalPath = assertNonEmptyString(physicalPath, 'physicalPath');
|
|
25669
|
-
try {
|
|
25670
|
-
if (this.artifacts.signing.algorithm !== 'EdDSA') {
|
|
25671
|
-
throw new Error('CSR creation only supported for Ed25519 signing keys in the default crypto provider');
|
|
25672
|
-
}
|
|
25673
|
-
const cryptoImpl = await ensureWebCrypto();
|
|
25674
|
-
const privateKey = await cryptoImpl.subtle.importKey('pkcs8', pemToArrayBuffer(this.signingPrivatePem), {
|
|
25675
|
-
name: 'Ed25519',
|
|
25676
|
-
}, false, ['sign']);
|
|
25677
|
-
const publicKeyDer = pemToArrayBuffer(this.signingPublicPem);
|
|
25678
|
-
const subjectPkInfo = AsnConvert.parse(publicKeyDer, SubjectPublicKeyInfo);
|
|
25679
|
-
const sanitizedLogicals = Array.isArray(logicals)
|
|
25680
|
-
? logicals.filter((value) => typeof value === 'string' && value.trim().length > 0)
|
|
25681
|
-
: [];
|
|
25682
|
-
const commonName = typeof subjectName === 'string' && subjectName.trim().length > 0
|
|
25683
|
-
? subjectName.trim()
|
|
25684
|
-
: trimmedNodeId;
|
|
25685
|
-
const subject = buildSubjectName(commonName);
|
|
25686
|
-
const attributes = new Attributes();
|
|
25687
|
-
if (sanitizedLogicals.length > 0) {
|
|
25688
|
-
const san = new SubjectAlternativeName(sanitizedLogicals.map((logical) => new GeneralName({
|
|
25689
|
-
uniformResourceIdentifier: `${LOGICAL_URI_PREFIX}${logical}`,
|
|
25690
|
-
})));
|
|
25691
|
-
const extensions = new Extensions([
|
|
25692
|
-
new Extension({
|
|
25693
|
-
extnID: id_ce_subjectAltName,
|
|
25694
|
-
critical: false,
|
|
25695
|
-
extnValue: new OctetString(AsnConvert.serialize(san)),
|
|
25696
|
-
}),
|
|
25697
|
-
]);
|
|
25698
|
-
attributes.push(new Attribute({
|
|
25699
|
-
type: EXTENSION_REQUEST_OID,
|
|
25700
|
-
values: [AsnConvert.serialize(extensions)],
|
|
25701
|
-
}));
|
|
25702
|
-
}
|
|
25703
|
-
const requestInfo = new CertificationRequestInfo({
|
|
25704
|
-
subject,
|
|
25705
|
-
subjectPKInfo: subjectPkInfo,
|
|
25706
|
-
attributes,
|
|
25707
|
-
});
|
|
25708
|
-
const requestInfoDer = AsnConvert.serialize(requestInfo);
|
|
25709
|
-
const signature = await cryptoImpl.subtle.sign('Ed25519', privateKey, requestInfoDer);
|
|
25710
|
-
const certificationRequest = new CertificationRequest({
|
|
25711
|
-
certificationRequestInfo: requestInfo,
|
|
25712
|
-
signatureAlgorithm: new AlgorithmIdentifier({
|
|
25713
|
-
algorithm: ED25519_OID,
|
|
25714
|
-
}),
|
|
25715
|
-
signature: encodeBitString(signature),
|
|
25716
|
-
});
|
|
25717
|
-
certificationRequest.certificationRequestInfoRaw = requestInfoDer;
|
|
25718
|
-
const csrDer = AsnConvert.serialize(certificationRequest);
|
|
25719
|
-
const csrPem = arrayBufferToPem(csrDer, CSR_PEM_TAG);
|
|
25720
|
-
logger$v.debug('csr_created', {
|
|
25721
|
-
node_id: trimmedNodeId,
|
|
25722
|
-
physical_path: trimmedPhysicalPath,
|
|
25723
|
-
logical_count: sanitizedLogicals.length,
|
|
25724
|
-
});
|
|
25725
|
-
return csrPem;
|
|
25726
|
-
}
|
|
25727
|
-
catch (error) {
|
|
25728
|
-
logger$v.error('csr_creation_failed', {
|
|
25729
|
-
node_id: trimmedNodeId,
|
|
25730
|
-
physical_path: trimmedPhysicalPath,
|
|
25731
|
-
error: error instanceof Error ? error.message : String(error),
|
|
25732
|
-
});
|
|
25733
|
-
throw error;
|
|
25734
|
-
}
|
|
25735
|
-
}
|
|
25736
25710
|
}
|
|
25737
25711
|
async function buildProviderArtifacts(options) {
|
|
25738
25712
|
const algorithm = normalizeAlgorithm(options.algorithm ?? readEnvAlgorithm());
|
|
@@ -25968,90 +25942,6 @@ function pemToDerBase64(pem) {
|
|
|
25968
25942
|
// Ensure the output is valid base64 without whitespace
|
|
25969
25943
|
return base64.replace(/\s+/g, '');
|
|
25970
25944
|
}
|
|
25971
|
-
let cryptoPromise = null;
|
|
25972
|
-
async function ensureWebCrypto() {
|
|
25973
|
-
if (typeof globalThis.crypto !== 'undefined' && globalThis.crypto?.subtle) {
|
|
25974
|
-
return globalThis.crypto;
|
|
25975
|
-
}
|
|
25976
|
-
if (!cryptoPromise) {
|
|
25977
|
-
if (typeof process !== 'undefined' &&
|
|
25978
|
-
typeof process.versions?.node === 'string') {
|
|
25979
|
-
cryptoPromise = import('node:crypto').then((module) => {
|
|
25980
|
-
const webcrypto = module.webcrypto;
|
|
25981
|
-
if (!webcrypto || !webcrypto.subtle) {
|
|
25982
|
-
throw new Error('WebCrypto API is not available in this Node.js runtime');
|
|
25983
|
-
}
|
|
25984
|
-
globalThis.crypto = webcrypto;
|
|
25985
|
-
return webcrypto;
|
|
25986
|
-
});
|
|
25987
|
-
}
|
|
25988
|
-
else {
|
|
25989
|
-
cryptoPromise = Promise.reject(new Error('WebCrypto API is not available in this environment'));
|
|
25990
|
-
}
|
|
25991
|
-
}
|
|
25992
|
-
return cryptoPromise;
|
|
25993
|
-
}
|
|
25994
|
-
function pemToArrayBuffer(pem) {
|
|
25995
|
-
const normalized = pem
|
|
25996
|
-
.replace(/-----BEGIN[^-]+-----/g, '')
|
|
25997
|
-
.replace(/-----END[^-]+-----/g, '')
|
|
25998
|
-
.replace(/\s+/g, '');
|
|
25999
|
-
const bytes = base64ToBytes$1(normalized);
|
|
26000
|
-
return bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength);
|
|
26001
|
-
}
|
|
26002
|
-
function base64ToBytes$1(base64) {
|
|
26003
|
-
if (typeof Buffer !== 'undefined') {
|
|
26004
|
-
const buffer = Buffer.from(base64, 'base64');
|
|
26005
|
-
const bytes = new Uint8Array(buffer.length);
|
|
26006
|
-
for (let i = 0; i < buffer.length; i += 1) {
|
|
26007
|
-
bytes[i] = buffer[i];
|
|
26008
|
-
}
|
|
26009
|
-
return bytes;
|
|
26010
|
-
}
|
|
26011
|
-
if (typeof atob === 'function') {
|
|
26012
|
-
const binary = atob(base64);
|
|
26013
|
-
const bytes = new Uint8Array(binary.length);
|
|
26014
|
-
for (let i = 0; i < binary.length; i += 1) {
|
|
26015
|
-
bytes[i] = binary.charCodeAt(i);
|
|
26016
|
-
}
|
|
26017
|
-
return bytes;
|
|
26018
|
-
}
|
|
26019
|
-
throw new Error('No base64 decoder available in this environment');
|
|
26020
|
-
}
|
|
26021
|
-
function arrayBufferToPem(buffer, tag) {
|
|
26022
|
-
const base64 = bytesToBase64(new Uint8Array(buffer));
|
|
26023
|
-
return `-----BEGIN ${tag}-----\n${formatPem(base64)}\n-----END ${tag}-----\n`;
|
|
26024
|
-
}
|
|
26025
|
-
function formatPem(base64) {
|
|
26026
|
-
const lines = [];
|
|
26027
|
-
for (let i = 0; i < base64.length; i += 64) {
|
|
26028
|
-
lines.push(base64.slice(i, i + 64));
|
|
26029
|
-
}
|
|
26030
|
-
return lines.join('\n');
|
|
26031
|
-
}
|
|
26032
|
-
function encodeBitString(signature) {
|
|
26033
|
-
const bytes = new Uint8Array(signature);
|
|
26034
|
-
const bitString = new Uint8Array(bytes.length + 1);
|
|
26035
|
-
bitString.set(bytes, 1);
|
|
26036
|
-
return bitString.buffer;
|
|
26037
|
-
}
|
|
26038
|
-
function buildSubjectName(commonName) {
|
|
26039
|
-
const attribute = new AttributeTypeAndValue({
|
|
26040
|
-
type: COMMON_NAME_OID,
|
|
26041
|
-
value: new AttributeValue({ utf8String: commonName }),
|
|
26042
|
-
});
|
|
26043
|
-
return new Name([new RelativeDistinguishedName([attribute])]);
|
|
26044
|
-
}
|
|
26045
|
-
function assertNonEmptyString(value, name) {
|
|
26046
|
-
if (typeof value !== 'string') {
|
|
26047
|
-
throw new TypeError(`${name} must be a string`);
|
|
26048
|
-
}
|
|
26049
|
-
const trimmed = value.trim();
|
|
26050
|
-
if (trimmed.length === 0) {
|
|
26051
|
-
throw new TypeError(`${name} must be a non-empty string`);
|
|
26052
|
-
}
|
|
26053
|
-
return trimmed;
|
|
26054
|
-
}
|
|
26055
25945
|
function cloneJson(value) {
|
|
26056
25946
|
return JSON.parse(JSON.stringify(value));
|
|
26057
25947
|
}
|
|
@@ -30499,6 +30389,8 @@ const ENV_VAR_DIRECT_INPAGE_CHANNEL = 'FAME_DIRECT_INPAGE_CHANNEL';
|
|
|
30499
30389
|
const ENV_VAR_ADMISSION_SERVICE_URL = 'FAME_ADMISSION_SERVICE_URL';
|
|
30500
30390
|
const DEFAULT_INPAGE_CHANNEL = 'naylence-fabric';
|
|
30501
30391
|
const PROFILE_NAME_WELCOME = 'welcome';
|
|
30392
|
+
const PROFILE_NAME_WELCOME_PKCE = 'welcome-pkce';
|
|
30393
|
+
const PROFILE_NAME_WELCOME_PKCE_ALIAS = 'welcome_pkce';
|
|
30502
30394
|
const PROFILE_NAME_DIRECT = 'direct';
|
|
30503
30395
|
const PROFILE_NAME_DIRECT_HTTP = 'direct-http';
|
|
30504
30396
|
const PROFILE_NAME_DIRECT_INPAGE = 'direct-inpage';
|
|
@@ -30559,6 +30451,7 @@ function createOAuthPkceTokenProviderConfig() {
|
|
|
30559
30451
|
}
|
|
30560
30452
|
const welcomeIsRoot = Expressions.env(ENV_VAR_IS_ROOT, 'false');
|
|
30561
30453
|
const welcomeTokenProvider = createOAuthTokenProviderConfig();
|
|
30454
|
+
const welcomePkceTokenProvider = createOAuthPkceTokenProviderConfig();
|
|
30562
30455
|
const WELCOME_SERVICE_PROFILE = {
|
|
30563
30456
|
type: 'WelcomeServiceClient',
|
|
30564
30457
|
is_root: welcomeIsRoot,
|
|
@@ -30572,6 +30465,19 @@ const WELCOME_SERVICE_PROFILE = {
|
|
|
30572
30465
|
tokenProvider: welcomeTokenProvider,
|
|
30573
30466
|
},
|
|
30574
30467
|
};
|
|
30468
|
+
const WELCOME_SERVICE_PKCE_PROFILE = {
|
|
30469
|
+
type: 'WelcomeServiceClient',
|
|
30470
|
+
is_root: welcomeIsRoot,
|
|
30471
|
+
isRoot: welcomeIsRoot,
|
|
30472
|
+
url: Expressions.env(ENV_VAR_ADMISSION_SERVICE_URL),
|
|
30473
|
+
supported_transports: ['websocket'],
|
|
30474
|
+
supportedTransports: ['websocket'],
|
|
30475
|
+
auth: {
|
|
30476
|
+
type: 'BearerTokenHeaderAuth',
|
|
30477
|
+
token_provider: welcomePkceTokenProvider,
|
|
30478
|
+
tokenProvider: welcomePkceTokenProvider,
|
|
30479
|
+
},
|
|
30480
|
+
};
|
|
30575
30481
|
const directGrantTokenProvider = createOAuthTokenProviderConfig();
|
|
30576
30482
|
const directGrant = {
|
|
30577
30483
|
type: 'WebSocketConnectionGrant',
|
|
@@ -30677,6 +30583,8 @@ const NOOP_PROFILE = {
|
|
|
30677
30583
|
};
|
|
30678
30584
|
const PROFILE_MAP$1 = {
|
|
30679
30585
|
[PROFILE_NAME_WELCOME]: WELCOME_SERVICE_PROFILE,
|
|
30586
|
+
[PROFILE_NAME_WELCOME_PKCE]: WELCOME_SERVICE_PKCE_PROFILE,
|
|
30587
|
+
[PROFILE_NAME_WELCOME_PKCE_ALIAS]: WELCOME_SERVICE_PKCE_PROFILE,
|
|
30680
30588
|
[PROFILE_NAME_DIRECT]: DIRECT_PROFILE,
|
|
30681
30589
|
[PROFILE_NAME_DIRECT_PKCE]: DIRECT_PKCE_PROFILE,
|
|
30682
30590
|
[PROFILE_NAME_DIRECT_PKCE_ALIAS]: DIRECT_PKCE_PROFILE,
|