@optimizely-opal/opal-tool-ocp-sdk 0.0.0-beta.11 → 0.0.0-beta.13

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 (58) hide show
  1. package/README.md +114 -55
  2. package/dist/auth/AuthUtils.d.ts +26 -0
  3. package/dist/auth/AuthUtils.d.ts.map +1 -0
  4. package/dist/auth/AuthUtils.js +109 -0
  5. package/dist/auth/AuthUtils.js.map +1 -0
  6. package/dist/auth/AuthUtils.test.d.ts +2 -0
  7. package/dist/auth/AuthUtils.test.d.ts.map +1 -0
  8. package/dist/auth/AuthUtils.test.js +601 -0
  9. package/dist/auth/AuthUtils.test.js.map +1 -0
  10. package/dist/auth/TokenVerifier.d.ts +31 -0
  11. package/dist/auth/TokenVerifier.d.ts.map +1 -0
  12. package/dist/auth/TokenVerifier.js +127 -0
  13. package/dist/auth/TokenVerifier.js.map +1 -0
  14. package/dist/auth/TokenVerifier.test.d.ts +2 -0
  15. package/dist/auth/TokenVerifier.test.d.ts.map +1 -0
  16. package/dist/auth/TokenVerifier.test.js +125 -0
  17. package/dist/auth/TokenVerifier.test.js.map +1 -0
  18. package/dist/function/GlobalToolFunction.d.ts +27 -0
  19. package/dist/function/GlobalToolFunction.d.ts.map +1 -0
  20. package/dist/function/GlobalToolFunction.js +53 -0
  21. package/dist/function/GlobalToolFunction.js.map +1 -0
  22. package/dist/function/GlobalToolFunction.test.d.ts +2 -0
  23. package/dist/function/GlobalToolFunction.test.d.ts.map +1 -0
  24. package/dist/function/GlobalToolFunction.test.js +425 -0
  25. package/dist/function/GlobalToolFunction.test.js.map +1 -0
  26. package/dist/function/ToolFunction.d.ts +3 -7
  27. package/dist/function/ToolFunction.d.ts.map +1 -1
  28. package/dist/function/ToolFunction.js +6 -10
  29. package/dist/function/ToolFunction.js.map +1 -1
  30. package/dist/function/ToolFunction.test.js +177 -196
  31. package/dist/function/ToolFunction.test.js.map +1 -1
  32. package/dist/index.d.ts +2 -0
  33. package/dist/index.d.ts.map +1 -1
  34. package/dist/index.js +2 -0
  35. package/dist/index.js.map +1 -1
  36. package/dist/service/Service.d.ts +14 -13
  37. package/dist/service/Service.d.ts.map +1 -1
  38. package/dist/service/Service.js +22 -16
  39. package/dist/service/Service.js.map +1 -1
  40. package/dist/service/Service.test.js +8 -3
  41. package/dist/service/Service.test.js.map +1 -1
  42. package/dist/types/Models.d.ts +5 -5
  43. package/dist/types/Models.d.ts.map +1 -1
  44. package/dist/types/Models.js +9 -9
  45. package/dist/types/Models.js.map +1 -1
  46. package/package.json +4 -3
  47. package/src/auth/AuthUtils.test.ts +729 -0
  48. package/src/auth/AuthUtils.ts +117 -0
  49. package/src/auth/TokenVerifier.test.ts +165 -0
  50. package/src/auth/TokenVerifier.ts +145 -0
  51. package/src/function/GlobalToolFunction.test.ts +505 -0
  52. package/src/function/GlobalToolFunction.ts +56 -0
  53. package/src/function/ToolFunction.test.ts +194 -214
  54. package/src/function/ToolFunction.ts +6 -10
  55. package/src/index.ts +2 -0
  56. package/src/service/Service.test.ts +8 -3
  57. package/src/service/Service.ts +53 -24
  58. package/src/types/Models.ts +4 -4
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TokenVerifier.d.ts","sourceRoot":"","sources":["../../src/auth/TokenVerifier.ts"],"names":[],"mappings":"AAkCA,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAA8B;IACrD,OAAO,CAAC,OAAO,CAAC,CAAS;IACzB,OAAO,CAAC,MAAM,CAAC,CAAS;IACxB,OAAO,CAAC,IAAI,CAAC,CAAwC;IACrD,OAAO,CAAC,WAAW,CAAkB;IAErC;;;;;OAKG;IACU,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC;IAQhE,OAAO,CAAC,MAAM,CAAC,WAAW;IAO1B;;;OAGG;WACiB,sBAAsB,IAAI,OAAO,CAAC,aAAa,CAAC;IAQpE;;OAEG;YACW,UAAU;IAyBxB;;OAEG;YACW,sBAAsB;YAetB,WAAW;CAsB1B;AAED,eAAO,MAAM,gBAAgB,QAAa,OAAO,CAAC,aAAa,CAA2C,CAAC"}
@@ -0,0 +1,127 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getTokenVerifier = exports.TokenVerifier = void 0;
4
+ const jose_1 = require("jose");
5
+ const app_sdk_1 = require("@zaiusinc/app-sdk");
6
+ /**
7
+ * Default JWKS cache expiration time in milliseconds (1 hour)
8
+ */
9
+ const DEFAULT_JWKS_EXPIRES_IN = 60 * 60 * 1000;
10
+ /**
11
+ * Default clock skew tolerance in seconds
12
+ */
13
+ const DEFAULT_LEEWAY = 30;
14
+ /**
15
+ * Expected JWT audience for token validation
16
+ */
17
+ const AUDIENCE = 'api://default';
18
+ /**
19
+ * Prep Base URL for Optimizely OAuth2 endpoints
20
+ */
21
+ const PREP_BASE_URL = 'https://prep.login.optimizely.com/oauth2/default';
22
+ /**
23
+ * Prod Base URL for Optimizely OAuth2 endpoints
24
+ */
25
+ const PROD_BASE_URL = 'https://login.optimizely.com/oauth2/default';
26
+ class TokenVerifier {
27
+ static instance = null;
28
+ jwksUri;
29
+ issuer;
30
+ jwks;
31
+ initialized = false;
32
+ /**
33
+ * Verify the provided Optimizely JWT token string
34
+ * @param token JWT token string to verify
35
+ * @returns boolean true if verification successful, false otherwise
36
+ * @throws Error if token is null, empty, or verifier is not properly configured
37
+ */
38
+ async verify(token) {
39
+ if (!token || token.trim().length === 0) {
40
+ throw new Error('Token cannot be null or empty');
41
+ }
42
+ return this.verifyToken(token);
43
+ }
44
+ static getInstance() {
45
+ if (!TokenVerifier.instance) {
46
+ TokenVerifier.instance = new TokenVerifier();
47
+ }
48
+ return TokenVerifier.instance;
49
+ }
50
+ /**
51
+ * Get singleton instance of TokenVerifier and ensure it's initialized
52
+ * @returns Promise<TokenVerifier> - initialized singleton instance
53
+ */
54
+ static async getInitializedInstance() {
55
+ const instance = TokenVerifier.getInstance();
56
+ if (!instance.initialized) {
57
+ await instance.initialize();
58
+ }
59
+ return instance;
60
+ }
61
+ /**
62
+ * Initialize the TokenVerifier with discovery document from well-known endpoint
63
+ */
64
+ async initialize() {
65
+ if (this.initialized) {
66
+ return;
67
+ }
68
+ try {
69
+ // Use prep URL when environment variable is set to 'staging', otherwise use prod
70
+ const environment = process.env.ENVIRONMENT || 'production';
71
+ const baseUrl = environment === 'staging' ? PREP_BASE_URL : PROD_BASE_URL;
72
+ const discoveryDocument = await this.fetchDiscoveryDocument(baseUrl);
73
+ this.issuer = discoveryDocument.issuer;
74
+ this.jwksUri = discoveryDocument.jwks_uri;
75
+ this.jwks = (0, jose_1.createRemoteJWKSet)(new URL(this.jwksUri), {
76
+ cacheMaxAge: DEFAULT_JWKS_EXPIRES_IN,
77
+ cooldownDuration: DEFAULT_JWKS_EXPIRES_IN
78
+ });
79
+ this.initialized = true;
80
+ app_sdk_1.logger.info(`TokenVerifier initialized with issuer: ${this.issuer} (environment: ${environment})`);
81
+ }
82
+ catch (error) {
83
+ app_sdk_1.logger.error('Failed to initialize TokenVerifier', error);
84
+ // Re-throw the original error to preserve specific error messages for tests
85
+ throw error;
86
+ }
87
+ }
88
+ /**
89
+ * Fetch discovery document from well-known endpoint
90
+ */
91
+ async fetchDiscoveryDocument(baseUrl) {
92
+ const wellKnownUrl = `${baseUrl}/.well-known/oauth-authorization-server`;
93
+ const response = await fetch(wellKnownUrl);
94
+ if (!response.ok) {
95
+ throw new Error(`Failed to fetch discovery document: ${response.status} ${response.statusText}`);
96
+ }
97
+ const discoveryDocument = await response.json();
98
+ if (!discoveryDocument.issuer || !discoveryDocument.jwks_uri) {
99
+ throw new Error('Invalid discovery document: missing issuer or jwks_uri');
100
+ }
101
+ return discoveryDocument;
102
+ }
103
+ async verifyToken(token) {
104
+ if (!this.initialized) {
105
+ throw new Error('TokenVerifier not initialized. Call initialize() first.');
106
+ }
107
+ if (!this.jwks || !this.issuer) {
108
+ throw new Error('TokenVerifier not properly configured.');
109
+ }
110
+ try {
111
+ await (0, jose_1.jwtVerify)(token, this.jwks, {
112
+ issuer: this.issuer,
113
+ audience: AUDIENCE,
114
+ clockTolerance: DEFAULT_LEEWAY,
115
+ });
116
+ return true;
117
+ }
118
+ catch (error) {
119
+ app_sdk_1.logger.error('Token verification failed:', error);
120
+ return false;
121
+ }
122
+ }
123
+ }
124
+ exports.TokenVerifier = TokenVerifier;
125
+ const getTokenVerifier = async () => TokenVerifier.getInitializedInstance();
126
+ exports.getTokenVerifier = getTokenVerifier;
127
+ //# sourceMappingURL=TokenVerifier.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TokenVerifier.js","sourceRoot":"","sources":["../../src/auth/TokenVerifier.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=TokenVerifier.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TokenVerifier.test.d.ts","sourceRoot":"","sources":["../../src/auth/TokenVerifier.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,125 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ // Mock the app-sdk module
4
+ jest.mock('@zaiusinc/app-sdk', () => ({
5
+ logger: {
6
+ info: jest.fn(),
7
+ error: jest.fn(),
8
+ warn: jest.fn(),
9
+ debug: jest.fn(),
10
+ },
11
+ }));
12
+ const TokenVerifier_1 = require("./TokenVerifier");
13
+ // Test constants
14
+ const TEST_ISSUER = 'https://prep.login.optimizely.com/oauth2/default';
15
+ const TEST_JWKS_URI = 'https://prep.login.optimizely.com/oauth2/v1/keys';
16
+ // Mock fetch globally
17
+ global.fetch = jest.fn();
18
+ describe('TokenVerifier', () => {
19
+ beforeEach(() => {
20
+ // Reset fetch mock
21
+ global.fetch.mockReset();
22
+ // Reset singleton instance for each test
23
+ TokenVerifier_1.TokenVerifier.instance = null;
24
+ });
25
+ describe('getInitializedInstance', () => {
26
+ it('should initialize successfully', async () => {
27
+ // Mock fetch for OAuth2 authorization server discovery
28
+ global.fetch.mockResolvedValue({
29
+ ok: true,
30
+ json: jest.fn().mockResolvedValue({
31
+ issuer: TEST_ISSUER,
32
+ jwks_uri: TEST_JWKS_URI
33
+ })
34
+ });
35
+ const tokenVerifier = await TokenVerifier_1.TokenVerifier.getInitializedInstance();
36
+ expect(tokenVerifier).toBeInstanceOf(TokenVerifier_1.TokenVerifier);
37
+ });
38
+ it('should throw error when discovery document is invalid', async () => {
39
+ global.fetch.mockResolvedValue({
40
+ ok: true,
41
+ json: jest.fn().mockResolvedValue({
42
+ // Missing issuer and jwks_uri
43
+ })
44
+ });
45
+ await expect(TokenVerifier_1.TokenVerifier.getInitializedInstance()).rejects.toThrow('Invalid discovery document: missing issuer or jwks_uri');
46
+ });
47
+ it('should throw error when discovery endpoint is unreachable', async () => {
48
+ global.fetch.mockResolvedValue({
49
+ ok: false,
50
+ status: 404,
51
+ statusText: 'Not Found'
52
+ });
53
+ await expect(TokenVerifier_1.TokenVerifier.getInitializedInstance()).rejects.toThrow('Failed to fetch discovery document: 404 Not Found');
54
+ });
55
+ });
56
+ describe('token verification', () => {
57
+ let tokenVerifier;
58
+ beforeEach(async () => {
59
+ // Mock successful initialization
60
+ global.fetch.mockResolvedValue({
61
+ ok: true,
62
+ json: jest.fn().mockResolvedValue({
63
+ issuer: TEST_ISSUER,
64
+ jwks_uri: TEST_JWKS_URI
65
+ })
66
+ });
67
+ tokenVerifier = await TokenVerifier_1.TokenVerifier.getInitializedInstance();
68
+ });
69
+ it('should throw error for empty token', async () => {
70
+ await expect(tokenVerifier.verify('')).rejects.toThrow('Token cannot be null or empty');
71
+ });
72
+ it('should throw error for undefined token', async () => {
73
+ await expect(tokenVerifier.verify(undefined)).rejects.toThrow('Token cannot be null or empty');
74
+ });
75
+ it('should throw error for whitespace-only token', async () => {
76
+ await expect(tokenVerifier.verify(' ')).rejects.toThrow('Token cannot be null or empty');
77
+ });
78
+ it('should return false for invalid token format', async () => {
79
+ const result = await tokenVerifier.verify('invalid.jwt.token');
80
+ expect(result).toBe(false);
81
+ });
82
+ });
83
+ describe('singleton pattern', () => {
84
+ it('should return same instance when called multiple times', async () => {
85
+ // Mock successful initialization
86
+ global.fetch.mockResolvedValue({
87
+ ok: true,
88
+ json: jest.fn().mockResolvedValue({
89
+ issuer: TEST_ISSUER,
90
+ jwks_uri: TEST_JWKS_URI
91
+ })
92
+ });
93
+ const instance1 = await TokenVerifier_1.TokenVerifier.getInitializedInstance();
94
+ const instance2 = await TokenVerifier_1.TokenVerifier.getInitializedInstance();
95
+ expect(instance1).toBe(instance2);
96
+ });
97
+ it('should call correct prod OAuth2 authorization server discovery URL', async () => {
98
+ const fetchSpy = jest.spyOn(global, 'fetch').mockResolvedValue({
99
+ ok: true,
100
+ json: jest.fn().mockResolvedValue({
101
+ issuer: TEST_ISSUER,
102
+ jwks_uri: TEST_JWKS_URI
103
+ })
104
+ });
105
+ await TokenVerifier_1.TokenVerifier.getInitializedInstance();
106
+ expect(fetchSpy).toHaveBeenCalledWith('https://login.optimizely.com/oauth2/default/.well-known/oauth-authorization-server');
107
+ });
108
+ it('should call correct prep OAuth2 authorization server discovery URL', async () => {
109
+ // Set environment variable to staging
110
+ process.env.ENVIRONMENT = 'staging';
111
+ const fetchSpy = jest.spyOn(global, 'fetch').mockResolvedValue({
112
+ ok: true,
113
+ json: jest.fn().mockResolvedValue({
114
+ issuer: TEST_ISSUER,
115
+ jwks_uri: TEST_JWKS_URI
116
+ })
117
+ });
118
+ await TokenVerifier_1.TokenVerifier.getInitializedInstance();
119
+ expect(fetchSpy).toHaveBeenCalledWith('https://prep.login.optimizely.com/oauth2/default/.well-known/oauth-authorization-server');
120
+ // Clean up environment variable
121
+ delete process.env.ENVIRONMENT;
122
+ });
123
+ });
124
+ });
125
+ //# sourceMappingURL=TokenVerifier.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TokenVerifier.test.js","sourceRoot":"","sources":["../../src/auth/TokenVerifier.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import { GlobalFunction, Response } from '@zaiusinc/app-sdk';
2
+ /**
3
+ * Abstract base class for global tool-based function execution
4
+ * Provides a standard interface for processing requests through registered tools
5
+ */
6
+ export declare abstract class GlobalToolFunction extends GlobalFunction {
7
+ /**
8
+ * Override this method to implement any required credentials and/or other configuration
9
+ * exist and are valid. Reasonable caching should be utilized to prevent excessive requests to external resources.
10
+ * @async
11
+ * @returns true if the opal function is ready to use
12
+ */
13
+ protected ready(): Promise<boolean>;
14
+ /**
15
+ * Process the incoming request using the tools service
16
+ *
17
+ * @returns Response as the HTTP response
18
+ */
19
+ perform(): Promise<Response>;
20
+ /**
21
+ * Authenticate the incoming request by validating only the OptiID token
22
+ *
23
+ * @returns true if authentication succeeds
24
+ */
25
+ private authorizeRequest;
26
+ }
27
+ //# sourceMappingURL=GlobalToolFunction.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GlobalToolFunction.d.ts","sourceRoot":"","sources":["../../src/function/GlobalToolFunction.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAmB,MAAM,mBAAmB,CAAC;AAI9E;;;GAGG;AACH,8BAAsB,kBAAmB,SAAQ,cAAc;IAE7D;;;;;OAKG;IACH,SAAS,CAAC,KAAK,IAAI,OAAO,CAAC,OAAO,CAAC;IAInC;;;;OAIG;IACU,OAAO,IAAI,OAAO,CAAC,QAAQ,CAAC;IAsBzC;;;;OAIG;YACW,gBAAgB;CAG/B"}
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GlobalToolFunction = void 0;
4
+ const app_sdk_1 = require("@zaiusinc/app-sdk");
5
+ const AuthUtils_1 = require("../auth/AuthUtils");
6
+ const Service_1 = require("../service/Service");
7
+ /**
8
+ * Abstract base class for global tool-based function execution
9
+ * Provides a standard interface for processing requests through registered tools
10
+ */
11
+ class GlobalToolFunction extends app_sdk_1.GlobalFunction {
12
+ /**
13
+ * Override this method to implement any required credentials and/or other configuration
14
+ * exist and are valid. Reasonable caching should be utilized to prevent excessive requests to external resources.
15
+ * @async
16
+ * @returns true if the opal function is ready to use
17
+ */
18
+ ready() {
19
+ return Promise.resolve(true);
20
+ }
21
+ /**
22
+ * Process the incoming request using the tools service
23
+ *
24
+ * @returns Response as the HTTP response
25
+ */
26
+ async perform() {
27
+ // Extract customer_id from auth data for global context attribution
28
+ const authInfo = (0, AuthUtils_1.extractAuthData)(this.request);
29
+ const customerId = authInfo?.authData?.credentials?.customer_id;
30
+ (0, app_sdk_1.amendLogContext)({
31
+ opalThreadId: this.request.headers.get('x-opal-thread-id') || '',
32
+ customerId: customerId || ''
33
+ });
34
+ if (!(await this.authorizeRequest())) {
35
+ return new app_sdk_1.Response(403, { error: 'Forbidden' });
36
+ }
37
+ if (this.request.path === '/ready') {
38
+ const isReady = await this.ready();
39
+ return new app_sdk_1.Response(200, { ready: isReady });
40
+ }
41
+ return Service_1.toolsService.processRequest(this.request, this);
42
+ }
43
+ /**
44
+ * Authenticate the incoming request by validating only the OptiID token
45
+ *
46
+ * @returns true if authentication succeeds
47
+ */
48
+ async authorizeRequest() {
49
+ return await (0, AuthUtils_1.authenticateGlobalRequest)(this.request);
50
+ }
51
+ }
52
+ exports.GlobalToolFunction = GlobalToolFunction;
53
+ //# sourceMappingURL=GlobalToolFunction.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GlobalToolFunction.js","sourceRoot":"","sources":["../../src/function/GlobalToolFunction.ts"],"names":[],"mappings":";;;AAAA,+CAA8E;AAC9E,iDAA+E;AAC/E,gDAAkD;AAElD;;;GAGG;AACH,MAAsB,kBAAmB,SAAQ,wBAAc;IAE7D;;;;;OAKG;IACO,KAAK;QACb,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/B,CAAC;IAED;;;;OAIG;IACI,KAAK,CAAC,OAAO;QAClB,oEAAoE;QACpE,MAAM,QAAQ,GAAG,IAAA,2BAAe,EAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC/C,MAAM,UAAU,GAAG,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,WAAW,CAAC;QAEhE,IAAA,yBAAe,EAAC;YACd,YAAY,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,IAAI,EAAE;YAChE,UAAU,EAAE,UAAU,IAAI,EAAE;SAC7B,CAAC,CAAC;QAEH,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,gBAAgB,EAAE,CAAC,EAAE,CAAC;YACrC,OAAO,IAAI,kBAAQ,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAC;QACnD,CAAC;QAED,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACnC,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;YACnC,OAAO,IAAI,kBAAQ,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;QAC/C,CAAC;QAED,OAAO,sBAAY,CAAC,cAAc,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IACzD,CAAC;IAED;;;;OAIG;IACK,KAAK,CAAC,gBAAgB;QAC5B,OAAO,MAAM,IAAA,qCAAyB,EAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACvD,CAAC;CACF;AA/CD,gDA+CC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=GlobalToolFunction.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GlobalToolFunction.test.d.ts","sourceRoot":"","sources":["../../src/function/GlobalToolFunction.test.ts"],"names":[],"mappings":""}