@naylence/runtime 0.3.5-test.910 → 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 +1915 -1214
- package/dist/browser/index.mjs +1910 -1209
- package/dist/cjs/naylence/fame/config/extended-fame-config.js +52 -0
- package/dist/cjs/naylence/fame/factory-manifest.js +2 -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 +901 -93
- package/dist/cjs/naylence/fame/http/openid-configuration-router.js +30 -32
- package/dist/cjs/naylence/fame/node/admission/admission-profile-factory.js +79 -0
- package/dist/cjs/naylence/fame/security/auth/oauth2-pkce-token-provider-factory.js +171 -0
- package/dist/cjs/naylence/fame/security/auth/oauth2-pkce-token-provider.js +560 -0
- package/dist/cjs/naylence/fame/security/crypto/providers/default-crypto-provider.js +0 -162
- package/dist/cjs/naylence/fame/telemetry/open-telemetry-trace-emitter-factory.js +19 -2
- package/dist/cjs/naylence/fame/telemetry/open-telemetry-trace-emitter.js +19 -9
- package/dist/cjs/naylence/fame/util/register-runtime-factories.js +6 -0
- package/dist/cjs/version.js +2 -2
- package/dist/esm/naylence/fame/config/extended-fame-config.js +52 -0
- package/dist/esm/naylence/fame/factory-manifest.js +2 -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 +901 -93
- package/dist/esm/naylence/fame/http/openid-configuration-router.js +30 -31
- package/dist/esm/naylence/fame/node/admission/admission-profile-factory.js +79 -0
- package/dist/esm/naylence/fame/security/auth/oauth2-pkce-token-provider-factory.js +134 -0
- package/dist/esm/naylence/fame/security/auth/oauth2-pkce-token-provider.js +555 -0
- package/dist/esm/naylence/fame/security/crypto/providers/default-crypto-provider.js +0 -162
- package/dist/esm/naylence/fame/telemetry/open-telemetry-trace-emitter-factory.js +19 -2
- package/dist/esm/naylence/fame/telemetry/open-telemetry-trace-emitter.js +19 -9
- package/dist/esm/naylence/fame/util/register-runtime-factories.js +6 -0
- package/dist/esm/version.js +2 -2
- package/dist/node/index.cjs +1911 -1210
- package/dist/node/index.mjs +1910 -1209
- package/dist/node/node.cjs +2945 -1439
- package/dist/node/node.mjs +2944 -1438
- package/dist/types/naylence/fame/factory-manifest.d.ts +1 -1
- 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 +75 -19
- package/dist/types/naylence/fame/http/openid-configuration-router.d.ts +8 -8
- package/dist/types/naylence/fame/security/auth/oauth2-pkce-token-provider-factory.d.ts +27 -0
- package/dist/types/naylence/fame/security/auth/oauth2-pkce-token-provider.d.ts +42 -0
- package/dist/types/naylence/fame/security/crypto/providers/default-crypto-provider.d.ts +0 -1
- package/dist/types/naylence/fame/telemetry/open-telemetry-trace-emitter.d.ts +4 -0
- package/dist/types/version.d.ts +1 -1
- package/package.json +4 -4
- package/dist/esm/naylence/fame/fastapi/oauth2-server.js +0 -205
- package/dist/types/naylence/fame/fastapi/oauth2-server.d.ts +0 -22
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*
|
|
5
5
|
* Provides the list of runtime factory modules for registration.
|
|
6
6
|
*/
|
|
7
|
-
export declare const MODULES: readonly ["./connector/broadcast-channel-connector-factory.js", "./connector/broadcast-channel-listener-factory.js", "./connector/http-listener-factory.js", "./connector/http-stateless-connector-factory.js", "./connector/inpage-connector-factory.js", "./connector/inpage-listener-factory.js", "./connector/websocket-connector-factory.js", "./connector/websocket-listener-factory.js", "./delivery/at-least-once-delivery-policy-factory.js", "./delivery/at-most-once-delivery-policy-factory.js", "./delivery/delivery-profile-factory.js", "./fabric/in-process-fame-fabric-factory.js", "./node/admission/admission-profile-factory.js", "./node/admission/direct-admission-client-factory.js", "./node/admission/noop-admission-client-factory.js", "./node/admission/welcome-service-client-factory.js", "./node/node-factory.js", "./placement/static-node-placement-strategy-factory.js", "./security/auth/bearer-token-header-auth-injection-strategy-factory.js", "./security/auth/default-authorizer-factory.js", "./security/auth/jwks-jwt-token-verifier-factory.js", "./security/auth/jwt-token-issuer-factory.js", "./security/auth/jwt-token-verifier-factory.js", "./security/auth/no-auth-injection-strategy-factory.js", "./security/auth/none-token-provider-factory.js", "./security/auth/noop-authorizer-factory.js", "./security/auth/noop-token-issuer-factory.js", "./security/auth/noop-token-verifier-factory.js", "./security/auth/oauth2-authorizer-factory.js", "./security/auth/oauth2-client-credentials-token-provider-factory.js", "./security/auth/query-param-auth-injection-strategy-factory.js", "./security/auth/shared-secret-authorizer-factory.js", "./security/auth/shared-secret-token-provider-factory.js", "./security/auth/shared-secret-token-verifier-factory.js", "./security/auth/static-token-provider-factory.js", "./security/auth/websocket-subprotocol-auth-injection-strategy-factory.js", "./security/credential/dev-fixed-key-credential-provider-factory.js", "./security/credential/env-credential-provider-factory.js", "./security/credential/none-credential-provider-factory.js", "./security/credential/prompt-credential-provider-factory.js", "./security/credential/secret-store-credential-provider-factory.js", "./security/credential/session-key-credential-provider-factory.js", "./security/credential/static-credential-provider-factory.js", "./security/default-security-manager-factory.js", "./security/encryption/noop-encryption-manager-factory.js", "./security/encryption/noop-secure-channel-manager-factory.js", "./security/keys/default-key-manager-factory.js", "./security/keys/in-memory-key-store-factory.js", "./security/keys/noop-key-validator-factory.js", "./security/node-security-profile-factory.js", "./security/policy/default-security-policy-factory.js", "./security/policy/no-security-policy-factory.js", "./security/signing/eddsa-envelope-signer-factory.js", "./security/signing/eddsa-envelope-verifier-factory.js", "./sentinel/capability-aware-routing-policy-factory.js", "./sentinel/composite-routing-policy-factory.js", "./sentinel/hybrid-path-routing-policy-factory.js", "./sentinel/load-balancing/composite-load-balancing-strategy-factory.js", "./sentinel/load-balancing/hrw-load-balancing-strategy-factory.js", "./sentinel/load-balancing/load-balancing-profile-factory.js", "./sentinel/load-balancing/random-load-balancing-strategy-factory.js", "./sentinel/load-balancing/round-robin-load-balancing-strategy-factory.js", "./sentinel/load-balancing/sticky-load-balancing-strategy-factory.js", "./sentinel/routing-profile-factory.js", "./sentinel/sentinel-factory.js", "./sentinel/store/route-store-factory.js", "./stickiness/simple-load-balancer-stickiness-manager-factory.js", "./telemetry/noop-trace-emitter-factory.js", "./telemetry/open-telemetry-trace-emitter-factory.js", "./telemetry/trace-emitter-profile-factory.js", "./welcome/default-welcome-service-factory.js"];
|
|
7
|
+
export declare const MODULES: readonly ["./connector/broadcast-channel-connector-factory.js", "./connector/broadcast-channel-listener-factory.js", "./connector/http-listener-factory.js", "./connector/http-stateless-connector-factory.js", "./connector/inpage-connector-factory.js", "./connector/inpage-listener-factory.js", "./connector/websocket-connector-factory.js", "./connector/websocket-listener-factory.js", "./delivery/at-least-once-delivery-policy-factory.js", "./delivery/at-most-once-delivery-policy-factory.js", "./delivery/delivery-profile-factory.js", "./fabric/in-process-fame-fabric-factory.js", "./node/admission/admission-profile-factory.js", "./node/admission/direct-admission-client-factory.js", "./node/admission/noop-admission-client-factory.js", "./node/admission/welcome-service-client-factory.js", "./node/node-factory.js", "./placement/static-node-placement-strategy-factory.js", "./security/auth/bearer-token-header-auth-injection-strategy-factory.js", "./security/auth/default-authorizer-factory.js", "./security/auth/jwks-jwt-token-verifier-factory.js", "./security/auth/jwt-token-issuer-factory.js", "./security/auth/jwt-token-verifier-factory.js", "./security/auth/no-auth-injection-strategy-factory.js", "./security/auth/none-token-provider-factory.js", "./security/auth/noop-authorizer-factory.js", "./security/auth/noop-token-issuer-factory.js", "./security/auth/noop-token-verifier-factory.js", "./security/auth/oauth2-authorizer-factory.js", "./security/auth/oauth2-client-credentials-token-provider-factory.js", "./security/auth/oauth2-pkce-token-provider-factory.js", "./security/auth/query-param-auth-injection-strategy-factory.js", "./security/auth/shared-secret-authorizer-factory.js", "./security/auth/shared-secret-token-provider-factory.js", "./security/auth/shared-secret-token-verifier-factory.js", "./security/auth/static-token-provider-factory.js", "./security/auth/websocket-subprotocol-auth-injection-strategy-factory.js", "./security/credential/dev-fixed-key-credential-provider-factory.js", "./security/credential/env-credential-provider-factory.js", "./security/credential/none-credential-provider-factory.js", "./security/credential/prompt-credential-provider-factory.js", "./security/credential/secret-store-credential-provider-factory.js", "./security/credential/session-key-credential-provider-factory.js", "./security/credential/static-credential-provider-factory.js", "./security/default-security-manager-factory.js", "./security/encryption/noop-encryption-manager-factory.js", "./security/encryption/noop-secure-channel-manager-factory.js", "./security/keys/default-key-manager-factory.js", "./security/keys/in-memory-key-store-factory.js", "./security/keys/noop-key-validator-factory.js", "./security/node-security-profile-factory.js", "./security/policy/default-security-policy-factory.js", "./security/policy/no-security-policy-factory.js", "./security/signing/eddsa-envelope-signer-factory.js", "./security/signing/eddsa-envelope-verifier-factory.js", "./sentinel/capability-aware-routing-policy-factory.js", "./sentinel/composite-routing-policy-factory.js", "./sentinel/hybrid-path-routing-policy-factory.js", "./sentinel/load-balancing/composite-load-balancing-strategy-factory.js", "./sentinel/load-balancing/hrw-load-balancing-strategy-factory.js", "./sentinel/load-balancing/load-balancing-profile-factory.js", "./sentinel/load-balancing/random-load-balancing-strategy-factory.js", "./sentinel/load-balancing/round-robin-load-balancing-strategy-factory.js", "./sentinel/load-balancing/sticky-load-balancing-strategy-factory.js", "./sentinel/routing-profile-factory.js", "./sentinel/sentinel-factory.js", "./sentinel/store/route-store-factory.js", "./stickiness/simple-load-balancer-stickiness-manager-factory.js", "./telemetry/noop-trace-emitter-factory.js", "./telemetry/open-telemetry-trace-emitter-factory.js", "./telemetry/trace-emitter-profile-factory.js", "./welcome/default-welcome-service-factory.js"];
|
|
8
8
|
export type FactoryModuleSpec = (typeof MODULES)[number];
|
|
9
9
|
export type FactoryModuleLoader = () => Promise<Record<string, unknown>>;
|
|
10
10
|
export declare const MODULE_LOADERS: Record<FactoryModuleSpec, FactoryModuleLoader>;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* JWKS (JSON Web Key Set) API
|
|
2
|
+
* JWKS (JSON Web Key Set) API plugin for Fastify
|
|
3
3
|
*
|
|
4
4
|
* Provides /.well-known/jwks.json endpoint for public key discovery
|
|
5
5
|
* Used by OAuth2/JWT token verification
|
|
6
6
|
*/
|
|
7
|
-
import {
|
|
7
|
+
import type { FastifyPluginAsync } from 'fastify';
|
|
8
8
|
import type { CryptoProvider } from '../security/crypto/providers/crypto-provider.js';
|
|
9
9
|
export interface CreateJwksRouterOptions {
|
|
10
10
|
/**
|
|
@@ -30,19 +30,19 @@ export interface CreateJwksRouterOptions {
|
|
|
30
30
|
keyTypes?: string[];
|
|
31
31
|
}
|
|
32
32
|
/**
|
|
33
|
-
* Create
|
|
33
|
+
* Create a Fastify plugin that exposes JWKS at /.well-known/jwks.json
|
|
34
34
|
*
|
|
35
35
|
* @param options - Router configuration options
|
|
36
|
-
* @returns
|
|
36
|
+
* @returns Fastify plugin with JWKS endpoint
|
|
37
37
|
*
|
|
38
38
|
* @example
|
|
39
39
|
* ```typescript
|
|
40
|
-
* import
|
|
40
|
+
* import Fastify from 'fastify';
|
|
41
41
|
* import { createJwksRouter } from '@naylence/runtime';
|
|
42
42
|
*
|
|
43
|
-
* const app =
|
|
43
|
+
* const app = Fastify();
|
|
44
44
|
* const cryptoProvider = new MyCryptoProvider();
|
|
45
|
-
* app.
|
|
45
|
+
* app.register(createJwksRouter({ cryptoProvider }));
|
|
46
46
|
* ```
|
|
47
47
|
*/
|
|
48
|
-
export declare function createJwksRouter(options?: CreateJwksRouterOptions):
|
|
48
|
+
export declare function createJwksRouter(options?: CreateJwksRouterOptions): FastifyPluginAsync;
|
|
@@ -21,11 +21,11 @@
|
|
|
21
21
|
* FAME_JWT_ISSUER: JWT issuer (default: https://auth.fame.fabric)
|
|
22
22
|
* FAME_JWT_ALGORITHM: JWT algorithm (default: EdDSA)
|
|
23
23
|
*/
|
|
24
|
-
import
|
|
24
|
+
import type { FastifyInstance } from 'fastify';
|
|
25
25
|
/**
|
|
26
|
-
* Create and configure the OAuth2
|
|
26
|
+
* Create and configure the OAuth2 Fastify application
|
|
27
27
|
*/
|
|
28
|
-
export declare function createApp(): Promise<
|
|
28
|
+
export declare function createApp(): Promise<FastifyInstance>;
|
|
29
29
|
/**
|
|
30
30
|
* Main entry point when run as CLI
|
|
31
31
|
*/
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* OAuth2 client credentials grant
|
|
2
|
+
* OAuth2 client credentials and authorization code (PKCE) grant router for Fastify
|
|
3
3
|
*
|
|
4
|
-
* Provides /oauth/token
|
|
5
|
-
* Implements OAuth2 client credentials grant with JWT token issuance
|
|
4
|
+
* Provides /oauth/token and /oauth/authorize endpoints for local development and testing.
|
|
5
|
+
* Implements OAuth2 client credentials grant with JWT token issuance and
|
|
6
|
+
* OAuth2 authorization code grant with PKCE verification.
|
|
6
7
|
*/
|
|
7
|
-
import {
|
|
8
|
+
import type { FastifyPluginAsync } from 'fastify';
|
|
8
9
|
import type { CryptoProvider } from '../security/crypto/providers/crypto-provider.js';
|
|
9
10
|
export interface CreateOAuth2TokenRouterOptions {
|
|
10
11
|
/**
|
|
@@ -44,12 +45,76 @@ export interface CreateOAuth2TokenRouterOptions {
|
|
|
44
45
|
* Default: EdDSA
|
|
45
46
|
*/
|
|
46
47
|
algorithm?: string;
|
|
48
|
+
/**
|
|
49
|
+
* Enable PKCE authorization code grant (default: true)
|
|
50
|
+
*/
|
|
51
|
+
enablePkce?: boolean;
|
|
52
|
+
/**
|
|
53
|
+
* Allow public clients (no client_secret) for PKCE exchange (default: true)
|
|
54
|
+
*/
|
|
55
|
+
allowPublicClients?: boolean;
|
|
56
|
+
/**
|
|
57
|
+
* Authorization code TTL in seconds (default: 300)
|
|
58
|
+
*/
|
|
59
|
+
authorizationCodeTtlSec?: number;
|
|
60
|
+
/**
|
|
61
|
+
* Enable developer login experience for authorization flows (default: false)
|
|
62
|
+
*/
|
|
63
|
+
enableDevLogin?: boolean;
|
|
64
|
+
/**
|
|
65
|
+
* Developer login username (required if enableDevLogin is true and not set via env)
|
|
66
|
+
*/
|
|
67
|
+
devLoginUsername?: string;
|
|
68
|
+
/**
|
|
69
|
+
* Developer login password (required if enableDevLogin is true and not set via env)
|
|
70
|
+
*/
|
|
71
|
+
devLoginPassword?: string;
|
|
72
|
+
/**
|
|
73
|
+
* Developer login session TTL in seconds (default: 3600)
|
|
74
|
+
*/
|
|
75
|
+
devLoginSessionTtlSec?: number;
|
|
76
|
+
/**
|
|
77
|
+
* Cookie name for developer login session (default: naylence_dev_session)
|
|
78
|
+
|
|
79
|
+
if (devLoginEnabled) {
|
|
80
|
+
cleanupLoginSessions(loginSessions, Date.now());
|
|
81
|
+
const activeSession = getActiveSession(
|
|
82
|
+
req,
|
|
83
|
+
loginSessions,
|
|
84
|
+
devLoginCookieName,
|
|
85
|
+
devLoginSessionTtlMs
|
|
86
|
+
);
|
|
87
|
+
if (!activeSession) {
|
|
88
|
+
const returnTo = sanitizeReturnTo(
|
|
89
|
+
req.originalUrl,
|
|
90
|
+
sessionCookiePath,
|
|
91
|
+
authorizationRedirectPath
|
|
92
|
+
);
|
|
93
|
+
const loginLocation = `${prefix}/login?return_to=${encodeURIComponent(
|
|
94
|
+
returnTo
|
|
95
|
+
)}`;
|
|
96
|
+
setNoCacheHeaders(res);
|
|
97
|
+
res.redirect(302, loginLocation);
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
*/
|
|
102
|
+
devLoginCookieName?: string;
|
|
103
|
+
/**
|
|
104
|
+
* Whether to mark the developer login cookie as secure (default: false)
|
|
105
|
+
*/
|
|
106
|
+
devLoginSecureCookie?: boolean;
|
|
107
|
+
/**
|
|
108
|
+
* Custom title for the developer login page (default: Developer Login)
|
|
109
|
+
*/
|
|
110
|
+
devLoginTitle?: string;
|
|
47
111
|
}
|
|
48
112
|
/**
|
|
49
|
-
* Create
|
|
113
|
+
* Create a Fastify plugin that implements OAuth2 token and authorization endpoints
|
|
114
|
+
* with support for client credentials and authorization code (PKCE) grants.
|
|
50
115
|
*
|
|
51
116
|
* @param options - Router configuration options
|
|
52
|
-
* @returns
|
|
117
|
+
* @returns Fastify plugin with OAuth2 token and authorization endpoints
|
|
53
118
|
*
|
|
54
119
|
* Environment Variables:
|
|
55
120
|
* FAME_JWT_CLIENT_ID: OAuth2 client identifier
|
|
@@ -58,17 +123,8 @@ export interface CreateOAuth2TokenRouterOptions {
|
|
|
58
123
|
* FAME_JWT_AUDIENCE: JWT audience claim (optional)
|
|
59
124
|
* FAME_JWT_ALGORITHM: JWT signing algorithm (optional, default: EdDSA)
|
|
60
125
|
* FAME_JWT_ALLOWED_SCOPES: Allowed scopes (optional, default: node.connect)
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
* import express from 'express';
|
|
65
|
-
* import { createOAuth2TokenRouter } from '@naylence/runtime';
|
|
66
|
-
*
|
|
67
|
-
* const app = express();
|
|
68
|
-
* app.use(express.urlencoded({ extended: true }));
|
|
69
|
-
*
|
|
70
|
-
* const cryptoProvider = new MyCryptoProvider();
|
|
71
|
-
* app.use(createOAuth2TokenRouter({ cryptoProvider }));
|
|
72
|
-
* ```
|
|
126
|
+
* FAME_OAUTH_ENABLE_PKCE: Enable PKCE authorization endpoints (optional, default: true)
|
|
127
|
+
* FAME_OAUTH_ALLOW_PUBLIC_CLIENTS: Allow PKCE exchanges without client_secret (optional, default: true)
|
|
128
|
+
* FAME_OAUTH_CODE_TTL_SEC: Authorization code TTL in seconds (optional, default: 300)
|
|
73
129
|
*/
|
|
74
|
-
export declare function createOAuth2TokenRouter(options: CreateOAuth2TokenRouterOptions):
|
|
130
|
+
export declare function createOAuth2TokenRouter(options: CreateOAuth2TokenRouterOptions): FastifyPluginAsync;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* OpenID Connect Discovery configuration
|
|
2
|
+
* OpenID Connect Discovery configuration plugin for Fastify
|
|
3
3
|
*
|
|
4
4
|
* Provides /.well-known/openid-configuration endpoint for OAuth2/OIDC client auto-discovery
|
|
5
5
|
*/
|
|
6
|
-
import {
|
|
6
|
+
import type { FastifyPluginAsync } from 'fastify';
|
|
7
7
|
export interface CreateOpenIDConfigurationRouterOptions {
|
|
8
8
|
/**
|
|
9
9
|
* Router prefix (default: empty string)
|
|
@@ -41,10 +41,10 @@ export interface CreateOpenIDConfigurationRouterOptions {
|
|
|
41
41
|
algorithm?: string;
|
|
42
42
|
}
|
|
43
43
|
/**
|
|
44
|
-
* Create
|
|
44
|
+
* Create a Fastify plugin that implements OpenID Connect Discovery
|
|
45
45
|
*
|
|
46
46
|
* @param options - Router configuration options
|
|
47
|
-
* @returns
|
|
47
|
+
* @returns Fastify plugin with OpenID configuration endpoint
|
|
48
48
|
*
|
|
49
49
|
* Environment Variables:
|
|
50
50
|
* FAME_JWT_ISSUER: JWT issuer claim (optional)
|
|
@@ -53,13 +53,13 @@ export interface CreateOpenIDConfigurationRouterOptions {
|
|
|
53
53
|
*
|
|
54
54
|
* @example
|
|
55
55
|
* ```typescript
|
|
56
|
-
* import
|
|
56
|
+
* import Fastify from 'fastify';
|
|
57
57
|
* import { createOpenIDConfigurationRouter } from '@naylence/runtime';
|
|
58
58
|
*
|
|
59
|
-
* const app =
|
|
60
|
-
* app.
|
|
59
|
+
* const app = Fastify();
|
|
60
|
+
* app.register(createOpenIDConfigurationRouter({
|
|
61
61
|
* issuer: 'https://auth.example.com',
|
|
62
62
|
* }));
|
|
63
63
|
* ```
|
|
64
64
|
*/
|
|
65
|
-
export declare function createOpenIDConfigurationRouter(options?: CreateOpenIDConfigurationRouterOptions):
|
|
65
|
+
export declare function createOpenIDConfigurationRouter(options?: CreateOpenIDConfigurationRouterOptions): FastifyPluginAsync;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { type SecretSourceType } from '../credential/secret-source.js';
|
|
2
|
+
import type { TokenProvider } from './token-provider.js';
|
|
3
|
+
import { TokenProviderFactory, type TokenProviderConfig } from './token-provider-factory.js';
|
|
4
|
+
export interface OAuth2PkceTokenProviderConfig extends TokenProviderConfig {
|
|
5
|
+
type: 'OAuth2PkceTokenProvider';
|
|
6
|
+
authorizeUrl: string;
|
|
7
|
+
tokenUrl: string;
|
|
8
|
+
redirectUri: string;
|
|
9
|
+
clientId: string;
|
|
10
|
+
username?: SecretSourceType;
|
|
11
|
+
clientSecret?: SecretSourceType;
|
|
12
|
+
scopes?: string[];
|
|
13
|
+
audience?: string;
|
|
14
|
+
codeChallengeMethod?: string;
|
|
15
|
+
codeVerifierLength?: number;
|
|
16
|
+
clockSkewSeconds?: number;
|
|
17
|
+
loginHintParam?: string;
|
|
18
|
+
}
|
|
19
|
+
export declare const FACTORY_META: {
|
|
20
|
+
readonly base: "TokenProviderFactory";
|
|
21
|
+
readonly key: "OAuth2PkceTokenProvider";
|
|
22
|
+
};
|
|
23
|
+
export declare class OAuth2PkceTokenProviderFactory extends TokenProviderFactory<OAuth2PkceTokenProviderConfig> {
|
|
24
|
+
readonly type = "OAuth2PkceTokenProvider";
|
|
25
|
+
create(config?: OAuth2PkceTokenProviderConfig | Record<string, unknown> | null): Promise<TokenProvider>;
|
|
26
|
+
}
|
|
27
|
+
export default OAuth2PkceTokenProviderFactory;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { type CredentialProvider } from '../credential/credential-provider.js';
|
|
2
|
+
import type { Token } from './token.js';
|
|
3
|
+
import type { TokenProvider } from './token-provider.js';
|
|
4
|
+
interface FetchLike {
|
|
5
|
+
(input: RequestInfo | URL, init?: RequestInit): Promise<Response>;
|
|
6
|
+
}
|
|
7
|
+
type PkceMethod = 'S256' | 'PLAIN';
|
|
8
|
+
export interface OAuth2PkceTokenProviderOptions {
|
|
9
|
+
authorizeUrl: string;
|
|
10
|
+
tokenUrl: string;
|
|
11
|
+
redirectUri: string;
|
|
12
|
+
clientId: string;
|
|
13
|
+
usernameProvider?: CredentialProvider;
|
|
14
|
+
clientSecretProvider?: CredentialProvider;
|
|
15
|
+
scopes?: string[];
|
|
16
|
+
audience?: string;
|
|
17
|
+
fetchImpl?: FetchLike;
|
|
18
|
+
clockSkewSeconds?: number;
|
|
19
|
+
codeVerifierLength?: number;
|
|
20
|
+
codeChallengeMethod?: PkceMethod;
|
|
21
|
+
loginHintParam?: string;
|
|
22
|
+
}
|
|
23
|
+
export declare class OAuth2PkceRedirectInitiatedError extends Error {
|
|
24
|
+
constructor(message?: string);
|
|
25
|
+
}
|
|
26
|
+
export declare class OAuth2PkceTokenProvider implements TokenProvider {
|
|
27
|
+
private cachedToken;
|
|
28
|
+
private readonly options;
|
|
29
|
+
constructor(rawOptions: OAuth2PkceTokenProviderOptions | Record<string, unknown>);
|
|
30
|
+
getToken(): Promise<Token>;
|
|
31
|
+
private isTokenFresh;
|
|
32
|
+
private beginBrowserAuthorization;
|
|
33
|
+
private navigate;
|
|
34
|
+
private tryCompletePendingAuthorization;
|
|
35
|
+
private isTokenCompatible;
|
|
36
|
+
private persistToken;
|
|
37
|
+
private buildAuthorizeUrl;
|
|
38
|
+
private resolveFetch;
|
|
39
|
+
private resolveOptionalSecret;
|
|
40
|
+
private exchangeToken;
|
|
41
|
+
}
|
|
42
|
+
export {};
|
|
@@ -57,6 +57,5 @@ export declare class DefaultCryptoProvider implements CryptoProvider {
|
|
|
57
57
|
prepareForAttach(nodeId: string, physicalPath: string, logicals: string[]): void;
|
|
58
58
|
setLogicals(logicals: string[]): void;
|
|
59
59
|
storeSignedCertificate(certificatePem: string, certificateChainPem?: string | null): void;
|
|
60
|
-
createCsr(nodeId: string, physicalPath: string, logicals: string[], subjectName?: string): Promise<string>;
|
|
61
60
|
}
|
|
62
61
|
export {};
|
|
@@ -3,8 +3,10 @@ import { BaseTraceEmitter } from './base-trace-emitter.js';
|
|
|
3
3
|
import type { TraceSpanOptions, TraceSpanScope } from './trace-emitter.js';
|
|
4
4
|
import type { OtelLifecycleControl } from './otel-setup.js';
|
|
5
5
|
import type { AuthInjectionStrategy } from '../security/auth/auth-injection-strategy.js';
|
|
6
|
+
type OtelApiBridge = Pick<typeof import('@opentelemetry/api'), 'trace' | 'SpanStatusCode'>;
|
|
6
7
|
export declare class OpenTelemetryTraceEmitter extends BaseTraceEmitter {
|
|
7
8
|
private readonly tracer;
|
|
9
|
+
private readonly otelApi;
|
|
8
10
|
private lifecycle;
|
|
9
11
|
private authStrategy;
|
|
10
12
|
private shutdownInvoked;
|
|
@@ -19,6 +21,8 @@ type OpenTelemetryTraceEmitterOptionsInput = {
|
|
|
19
21
|
serviceName?: string;
|
|
20
22
|
service_name?: string;
|
|
21
23
|
tracer?: Tracer;
|
|
24
|
+
otelApi?: OtelApiBridge;
|
|
25
|
+
otel_api?: OtelApiBridge;
|
|
22
26
|
lifecycle?: OtelLifecycleControl | null;
|
|
23
27
|
lifeCycle?: OtelLifecycleControl | null;
|
|
24
28
|
life_cycle?: OtelLifecycleControl | null;
|
package/dist/types/version.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@naylence/runtime",
|
|
3
|
-
"version": "0.3.5-test.
|
|
3
|
+
"version": "0.3.5-test.913",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Naylence Runtime - Complete TypeScript runtime",
|
|
6
6
|
"author": "Naylence Dev <naylencedev@gmail.com>",
|
|
@@ -183,8 +183,6 @@
|
|
|
183
183
|
"@peculiar/asn1-csr": "^2.5.0",
|
|
184
184
|
"@peculiar/asn1-schema": "^2.5.0",
|
|
185
185
|
"@peculiar/asn1-x509": "^2.5.0",
|
|
186
|
-
"@types/express": "^5.0.3",
|
|
187
|
-
"express": "^5.1.0",
|
|
188
186
|
"fastify": "^5.6.1",
|
|
189
187
|
"jose": "^6.1.0",
|
|
190
188
|
"yaml": "^2.6.0",
|
|
@@ -217,6 +215,7 @@
|
|
|
217
215
|
"@types/better-sqlite3": "^7.6.13",
|
|
218
216
|
"@types/jest": "^29.5.14",
|
|
219
217
|
"@types/node": "^24.6.0",
|
|
218
|
+
"@types/supertest": "^2.0.16",
|
|
220
219
|
"@types/ws": "^8.5.10",
|
|
221
220
|
"@typescript-eslint/eslint-plugin": "^8.45.0",
|
|
222
221
|
"@typescript-eslint/parser": "^8.45.0",
|
|
@@ -233,6 +232,7 @@
|
|
|
233
232
|
"rimraf": "^6.0.1",
|
|
234
233
|
"rollup": "^4.52.3",
|
|
235
234
|
"size-limit": "^11.1.5",
|
|
235
|
+
"supertest": "^7.1.3",
|
|
236
236
|
"ts-jest": "^29.4.5",
|
|
237
237
|
"tslib": "^2.6.2",
|
|
238
238
|
"typescript": "^5.3.2",
|
|
@@ -252,4 +252,4 @@
|
|
|
252
252
|
"engines": {
|
|
253
253
|
"node": ">=18.0.0"
|
|
254
254
|
}
|
|
255
|
-
}
|
|
255
|
+
}
|
|
@@ -1,205 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* OAuth2 Development Server - Simple token server for local testing
|
|
4
|
-
*
|
|
5
|
-
* WARNING: This is a DEVELOPMENT ONLY server. Do NOT use in production!
|
|
6
|
-
*
|
|
7
|
-
* Provides a minimal OAuth2 client credentials flow implementation
|
|
8
|
-
* for local testing and development of Fame applications.
|
|
9
|
-
*
|
|
10
|
-
* Environment Variables:
|
|
11
|
-
* - FAME_LOG_LEVEL: Log level (default: trace)
|
|
12
|
-
* - APP_HOST: Server host (default: 0.0.0.0)
|
|
13
|
-
* - APP_PORT: Server port (default: 8099)
|
|
14
|
-
* - FAME_JWT_CLIENT_ID: Expected OAuth2 client ID
|
|
15
|
-
* - FAME_JWT_CLIENT_SECRET: Expected OAuth2 client secret
|
|
16
|
-
* - FAME_JWT_ISSUER: JWT issuer (default: https://oauth2-server)
|
|
17
|
-
* - FAME_JWT_AUDIENCE: JWT audience (default: fame.fabric)
|
|
18
|
-
* - FAME_JWT_ALGORITHM: JWT algorithm (default: EdDSA)
|
|
19
|
-
*/
|
|
20
|
-
import Fastify from 'fastify';
|
|
21
|
-
import formbody from '@fastify/formbody';
|
|
22
|
-
import * as jose from 'jose';
|
|
23
|
-
import { generateKeyPair } from 'crypto';
|
|
24
|
-
import { promisify } from 'util';
|
|
25
|
-
import { enableLogging, getLogger } from '../util/logging.js';
|
|
26
|
-
const generateKeyPairAsync = promisify(generateKeyPair);
|
|
27
|
-
const ENV_VAR_LOG_LEVEL = 'FAME_LOG_LEVEL';
|
|
28
|
-
const ENV_VAR_CLIENT_ID = 'FAME_JWT_CLIENT_ID';
|
|
29
|
-
const ENV_VAR_CLIENT_SECRET = 'FAME_JWT_CLIENT_SECRET';
|
|
30
|
-
const ENV_VAR_JWT_ISSUER = 'FAME_JWT_ISSUER';
|
|
31
|
-
const ENV_VAR_JWT_AUDIENCE = 'FAME_JWT_AUDIENCE';
|
|
32
|
-
const ENV_VAR_JWT_ALGORITHM = 'FAME_JWT_ALGORITHM';
|
|
33
|
-
const logger = getLogger('naylence.fame.fastapi.oauth2_server');
|
|
34
|
-
// Global keypair for signing tokens
|
|
35
|
-
let signingKey; // jose.KeyLike type not exported
|
|
36
|
-
let publicKey; // jose.KeyLike type not exported
|
|
37
|
-
let publicJWK;
|
|
38
|
-
async function initializeKeys() {
|
|
39
|
-
const algorithm = process.env[ENV_VAR_JWT_ALGORITHM] || 'EdDSA';
|
|
40
|
-
if (algorithm === 'EdDSA') {
|
|
41
|
-
const { privateKey, publicKey: pubKey } = await generateKeyPairAsync('ed25519', {
|
|
42
|
-
privateKeyEncoding: { type: 'pkcs8', format: 'pem' },
|
|
43
|
-
publicKeyEncoding: { type: 'spki', format: 'pem' },
|
|
44
|
-
});
|
|
45
|
-
signingKey = await jose.importPKCS8(privateKey, 'EdDSA');
|
|
46
|
-
publicKey = await jose.importSPKI(pubKey, 'EdDSA');
|
|
47
|
-
publicJWK = await jose.exportJWK(publicKey);
|
|
48
|
-
publicJWK.kid = 'dev-key-1';
|
|
49
|
-
publicJWK.alg = 'EdDSA';
|
|
50
|
-
publicJWK.use = 'sig';
|
|
51
|
-
}
|
|
52
|
-
else {
|
|
53
|
-
// RS256 fallback
|
|
54
|
-
const { privateKey, publicKey: pubKey } = await generateKeyPairAsync('rsa', {
|
|
55
|
-
modulusLength: 2048,
|
|
56
|
-
privateKeyEncoding: { type: 'pkcs8', format: 'pem' },
|
|
57
|
-
publicKeyEncoding: { type: 'spki', format: 'pem' },
|
|
58
|
-
});
|
|
59
|
-
signingKey = await jose.importPKCS8(privateKey, 'RS256');
|
|
60
|
-
publicKey = await jose.importSPKI(pubKey, 'RS256');
|
|
61
|
-
publicJWK = await jose.exportJWK(publicKey);
|
|
62
|
-
publicJWK.kid = 'dev-key-1';
|
|
63
|
-
publicJWK.alg = 'RS256';
|
|
64
|
-
publicJWK.use = 'sig';
|
|
65
|
-
}
|
|
66
|
-
logger.info('oauth2_server_keys_initialized', { algorithm });
|
|
67
|
-
}
|
|
68
|
-
async function createApp() {
|
|
69
|
-
await initializeKeys();
|
|
70
|
-
const logLevel = (process.env[ENV_VAR_LOG_LEVEL] || 'info').toLowerCase();
|
|
71
|
-
const fastify = Fastify({
|
|
72
|
-
logger: {
|
|
73
|
-
level: logLevel === 'trace' ? 'debug' : logLevel,
|
|
74
|
-
},
|
|
75
|
-
});
|
|
76
|
-
// Register formbody plugin to parse application/x-www-form-urlencoded
|
|
77
|
-
await fastify.register(formbody);
|
|
78
|
-
const issuer = process.env[ENV_VAR_JWT_ISSUER] || 'https://oauth2-server';
|
|
79
|
-
const audience = process.env[ENV_VAR_JWT_AUDIENCE] || 'fame.fabric';
|
|
80
|
-
const algorithm = process.env[ENV_VAR_JWT_ALGORITHM] || 'EdDSA';
|
|
81
|
-
const expectedClientId = process.env[ENV_VAR_CLIENT_ID];
|
|
82
|
-
const expectedClientSecret = process.env[ENV_VAR_CLIENT_SECRET];
|
|
83
|
-
// OAuth2 token endpoint
|
|
84
|
-
fastify.post('/oauth/token', async (request, reply) => {
|
|
85
|
-
const { grant_type, client_id, client_secret, scope } = request.body;
|
|
86
|
-
// Validate grant type
|
|
87
|
-
if (grant_type !== 'client_credentials') {
|
|
88
|
-
return reply.status(400).send({
|
|
89
|
-
error: 'unsupported_grant_type',
|
|
90
|
-
error_description: 'Only client_credentials grant type is supported',
|
|
91
|
-
});
|
|
92
|
-
}
|
|
93
|
-
// Validate client credentials
|
|
94
|
-
if (!expectedClientId || !expectedClientSecret) {
|
|
95
|
-
logger.error('oauth2_server_missing_credentials', {
|
|
96
|
-
message: 'FAME_JWT_CLIENT_ID and FAME_JWT_CLIENT_SECRET must be set',
|
|
97
|
-
});
|
|
98
|
-
return reply.status(500).send({
|
|
99
|
-
error: 'server_error',
|
|
100
|
-
error_description: 'Server not configured properly',
|
|
101
|
-
});
|
|
102
|
-
}
|
|
103
|
-
if (client_id !== expectedClientId ||
|
|
104
|
-
client_secret !== expectedClientSecret) {
|
|
105
|
-
return reply.status(401).send({
|
|
106
|
-
error: 'invalid_client',
|
|
107
|
-
error_description: 'Invalid client credentials',
|
|
108
|
-
});
|
|
109
|
-
}
|
|
110
|
-
// Generate JWT
|
|
111
|
-
const now = Math.floor(Date.now() / 1000);
|
|
112
|
-
const expiresIn = 3600; // 1 hour
|
|
113
|
-
const payload = {
|
|
114
|
-
iss: issuer,
|
|
115
|
-
sub: client_id,
|
|
116
|
-
aud: audience,
|
|
117
|
-
iat: now,
|
|
118
|
-
exp: now + expiresIn,
|
|
119
|
-
scope: scope || 'node.connect',
|
|
120
|
-
};
|
|
121
|
-
const token = await new jose.SignJWT(payload)
|
|
122
|
-
.setProtectedHeader({ alg: algorithm, kid: 'dev-key-1' })
|
|
123
|
-
.sign(signingKey);
|
|
124
|
-
logger.debug('oauth2_token_issued', {
|
|
125
|
-
client_id,
|
|
126
|
-
scope: payload.scope,
|
|
127
|
-
expires_in: expiresIn,
|
|
128
|
-
});
|
|
129
|
-
return {
|
|
130
|
-
access_token: token,
|
|
131
|
-
token_type: 'Bearer',
|
|
132
|
-
expires_in: expiresIn,
|
|
133
|
-
scope: payload.scope,
|
|
134
|
-
};
|
|
135
|
-
});
|
|
136
|
-
// JWKS endpoint for public key distribution
|
|
137
|
-
fastify.get('/.well-known/jwks.json', async () => {
|
|
138
|
-
return {
|
|
139
|
-
keys: [publicJWK],
|
|
140
|
-
};
|
|
141
|
-
});
|
|
142
|
-
// OpenID configuration endpoint
|
|
143
|
-
fastify.get('/.well-known/openid-configuration', async () => {
|
|
144
|
-
const baseUrl = issuer;
|
|
145
|
-
return {
|
|
146
|
-
issuer: baseUrl,
|
|
147
|
-
token_endpoint: `${baseUrl}/oauth/token`,
|
|
148
|
-
jwks_uri: `${baseUrl}/.well-known/jwks.json`,
|
|
149
|
-
grant_types_supported: ['client_credentials'],
|
|
150
|
-
response_types_supported: ['token'],
|
|
151
|
-
token_endpoint_auth_methods_supported: [
|
|
152
|
-
'client_secret_post',
|
|
153
|
-
'client_secret_basic',
|
|
154
|
-
],
|
|
155
|
-
};
|
|
156
|
-
});
|
|
157
|
-
// Health check
|
|
158
|
-
fastify.get('/health', async () => {
|
|
159
|
-
return { status: 'healthy', service: 'oauth2-dev-server' };
|
|
160
|
-
});
|
|
161
|
-
return fastify;
|
|
162
|
-
}
|
|
163
|
-
async function main() {
|
|
164
|
-
try {
|
|
165
|
-
const logLevel = process.env[ENV_VAR_LOG_LEVEL] || 'trace';
|
|
166
|
-
enableLogging(logLevel);
|
|
167
|
-
const app = await createApp();
|
|
168
|
-
const host = process.env.APP_HOST || '0.0.0.0';
|
|
169
|
-
const port = parseInt(process.env.APP_PORT || '8099', 10);
|
|
170
|
-
await app.listen({ host, port });
|
|
171
|
-
logger.info('oauth2_dev_server_started', {
|
|
172
|
-
host,
|
|
173
|
-
port,
|
|
174
|
-
logLevel,
|
|
175
|
-
});
|
|
176
|
-
console.log(`\n⚠️ OAuth2 Development Server (DO NOT USE IN PRODUCTION)`);
|
|
177
|
-
console.log(`📍 Listening on http://${host}:${port}`);
|
|
178
|
-
console.log(`🔑 Token endpoint: http://${host}:${port}/oauth/token`);
|
|
179
|
-
console.log(`📜 JWKS endpoint: http://${host}:${port}/.well-known/jwks.json\n`);
|
|
180
|
-
}
|
|
181
|
-
catch (error) {
|
|
182
|
-
logger.error('oauth2_dev_server_failed_to_start', {
|
|
183
|
-
error: error instanceof Error ? error.message : String(error),
|
|
184
|
-
});
|
|
185
|
-
console.error('Failed to start OAuth2 Development Server:', error);
|
|
186
|
-
process.exit(1);
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
// Handle graceful shutdown
|
|
190
|
-
process.on('SIGTERM', () => {
|
|
191
|
-
logger.info('oauth2_dev_server_shutting_down', { signal: 'SIGTERM' });
|
|
192
|
-
process.exit(0);
|
|
193
|
-
});
|
|
194
|
-
process.on('SIGINT', () => {
|
|
195
|
-
logger.info('oauth2_dev_server_shutting_down', { signal: 'SIGINT' });
|
|
196
|
-
process.exit(0);
|
|
197
|
-
});
|
|
198
|
-
// Start server if run directly
|
|
199
|
-
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
200
|
-
main().catch((error) => {
|
|
201
|
-
console.error('Fatal error:', error);
|
|
202
|
-
process.exit(1);
|
|
203
|
-
});
|
|
204
|
-
}
|
|
205
|
-
export { createApp };
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* OAuth2 Development Server - Simple token server for local testing
|
|
4
|
-
*
|
|
5
|
-
* WARNING: This is a DEVELOPMENT ONLY server. Do NOT use in production!
|
|
6
|
-
*
|
|
7
|
-
* Provides a minimal OAuth2 client credentials flow implementation
|
|
8
|
-
* for local testing and development of Fame applications.
|
|
9
|
-
*
|
|
10
|
-
* Environment Variables:
|
|
11
|
-
* - FAME_LOG_LEVEL: Log level (default: trace)
|
|
12
|
-
* - APP_HOST: Server host (default: 0.0.0.0)
|
|
13
|
-
* - APP_PORT: Server port (default: 8099)
|
|
14
|
-
* - FAME_JWT_CLIENT_ID: Expected OAuth2 client ID
|
|
15
|
-
* - FAME_JWT_CLIENT_SECRET: Expected OAuth2 client secret
|
|
16
|
-
* - FAME_JWT_ISSUER: JWT issuer (default: https://oauth2-server)
|
|
17
|
-
* - FAME_JWT_AUDIENCE: JWT audience (default: fame.fabric)
|
|
18
|
-
* - FAME_JWT_ALGORITHM: JWT algorithm (default: EdDSA)
|
|
19
|
-
*/
|
|
20
|
-
import type { FastifyInstance } from 'fastify';
|
|
21
|
-
declare function createApp(): Promise<FastifyInstance>;
|
|
22
|
-
export { createApp };
|