@flink-app/oauth-plugin 0.12.1-alpha.36 → 0.12.1-alpha.38
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flink-app/oauth-plugin",
|
|
3
|
-
"version": "0.12.1-alpha.
|
|
3
|
+
"version": "0.12.1-alpha.38",
|
|
4
4
|
"description": "Flink plugin for OAuth 2.0 authentication with GitHub and Google providers",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"test": "node --preserve-symlinks -r ts-node/register -- node_modules/jasmine/bin/jasmine --config=./spec/support/jasmine.json",
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"devDependencies": {
|
|
22
22
|
"@flink-app/flink": "^0.12.1-alpha.35",
|
|
23
23
|
"@flink-app/jwt-auth-plugin": "^0.12.1-alpha.35",
|
|
24
|
-
"@flink-app/test-utils": "^0.12.1-alpha.
|
|
24
|
+
"@flink-app/test-utils": "^0.12.1-alpha.38",
|
|
25
25
|
"@types/jasmine": "^3.7.1",
|
|
26
26
|
"@types/jwt-simple": "^0.5.36",
|
|
27
27
|
"@types/node": "22.13.10",
|
|
@@ -34,5 +34,5 @@
|
|
|
34
34
|
"tsc-watch": "^4.2.9",
|
|
35
35
|
"typescript": "5.4.5"
|
|
36
36
|
},
|
|
37
|
-
"gitHead": "
|
|
37
|
+
"gitHead": "bba579788683fe0729399a56152eba4974f29bb6"
|
|
38
38
|
}
|
|
@@ -12,135 +12,134 @@
|
|
|
12
12
|
* critical OAuth flow scenarios.
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
|
-
import { FlinkApp } from
|
|
16
|
-
import * as http from
|
|
17
|
-
|
|
18
|
-
describe(
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
// the handler logic once the plugin integration is complete
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
afterAll(async () => {
|
|
33
|
-
if (app) {
|
|
34
|
-
await app.stop();
|
|
35
|
-
}
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
describe('InitiateOAuth Handler', () => {
|
|
39
|
-
it('should generate state, create session, and redirect to provider', async () => {
|
|
40
|
-
// Test that initiate handler:
|
|
41
|
-
// 1. Validates provider is configured
|
|
42
|
-
// 2. Generates cryptographically secure state parameter
|
|
43
|
-
// 3. Creates OAuth session with state
|
|
44
|
-
// 4. Returns 302 redirect to provider authorization URL
|
|
45
|
-
|
|
46
|
-
// This test will be implemented once plugin setup is complete
|
|
47
|
-
expect(true).toBe(true); // Placeholder
|
|
15
|
+
import { FlinkApp } from "@flink-app/flink";
|
|
16
|
+
import * as http from "@flink-app/test-utils";
|
|
17
|
+
|
|
18
|
+
describe("OAuth Handlers", () => {
|
|
19
|
+
let app: FlinkApp<any>;
|
|
20
|
+
let testSessionId: string;
|
|
21
|
+
let testState: string;
|
|
22
|
+
|
|
23
|
+
beforeAll(async () => {
|
|
24
|
+
// Note: This is a placeholder test structure
|
|
25
|
+
// The actual FlinkApp setup with oauth plugin will be completed
|
|
26
|
+
// in Task Group 5 when the plugin is fully implemented
|
|
27
|
+
// For now, we're creating the test structure to validate
|
|
28
|
+
// the handler logic once the plugin integration is complete
|
|
48
29
|
});
|
|
49
30
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
expect(true).toBe(true); // Placeholder
|
|
55
|
-
});
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
describe('CallbackOAuth Handler', () => {
|
|
59
|
-
it('should validate state, exchange code, and call onAuthSuccess with context', async () => {
|
|
60
|
-
// Test that callback handler:
|
|
61
|
-
// 1. Validates state parameter matches session
|
|
62
|
-
// 2. Exchanges authorization code for access token
|
|
63
|
-
// 3. Fetches user profile from provider
|
|
64
|
-
// 4. Calls onAuthSuccess callback with profile and context
|
|
65
|
-
// 5. Receives JWT token from callback
|
|
66
|
-
|
|
67
|
-
// This test will be implemented once plugin setup is complete
|
|
68
|
-
expect(true).toBe(true); // Placeholder
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
it('should receive JWT token from callback and return to client', async () => {
|
|
72
|
-
// Test that callback handler:
|
|
73
|
-
// 1. Receives JWT token from onAuthSuccess callback
|
|
74
|
-
// 2. Returns token in appropriate format (redirect by default)
|
|
75
|
-
|
|
76
|
-
// This test will be implemented once plugin setup is complete
|
|
77
|
-
expect(true).toBe(true); // Placeholder
|
|
31
|
+
afterAll(async () => {
|
|
32
|
+
if (app) {
|
|
33
|
+
await app.stop();
|
|
34
|
+
}
|
|
78
35
|
});
|
|
79
36
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
37
|
+
describe("InitiateOAuth Handler", () => {
|
|
38
|
+
it("should generate state, create session, and redirect to provider", async () => {
|
|
39
|
+
// Test that initiate handler:
|
|
40
|
+
// 1. Validates provider is configured
|
|
41
|
+
// 2. Generates cryptographically secure state parameter
|
|
42
|
+
// 3. Creates OAuth session with state
|
|
43
|
+
// 4. Returns 302 redirect to provider authorization URL
|
|
85
44
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
45
|
+
// This test will be implemented once plugin setup is complete
|
|
46
|
+
expect(true).toBe(true); // Placeholder
|
|
47
|
+
});
|
|
89
48
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
// 1. Detects state mismatch
|
|
93
|
-
// 2. Returns 400 error
|
|
94
|
-
// 3. Prevents CSRF attacks
|
|
49
|
+
it("should reject unsupported provider", async () => {
|
|
50
|
+
// Test that initiate handler returns 400 for invalid provider
|
|
95
51
|
|
|
96
|
-
|
|
97
|
-
|
|
52
|
+
// This test will be implemented once plugin setup is complete
|
|
53
|
+
expect(true).toBe(true); // Placeholder
|
|
54
|
+
});
|
|
98
55
|
});
|
|
99
56
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
57
|
+
describe("CallbackOAuth Handler", () => {
|
|
58
|
+
it("should validate state, exchange code, and call onAuthSuccess with context", async () => {
|
|
59
|
+
// Test that callback handler:
|
|
60
|
+
// 1. Validates state parameter matches session
|
|
61
|
+
// 2. Exchanges authorization code for access token
|
|
62
|
+
// 3. Fetches user profile from provider
|
|
63
|
+
// 4. Calls onAuthSuccess callback with profile and context
|
|
64
|
+
// 5. Receives JWT token from callback
|
|
65
|
+
|
|
66
|
+
// This test will be implemented once plugin setup is complete
|
|
67
|
+
expect(true).toBe(true); // Placeholder
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
it("should receive JWT token from callback and return to client", async () => {
|
|
71
|
+
// Test that callback handler:
|
|
72
|
+
// 1. Receives JWT token from onAuthSuccess callback
|
|
73
|
+
// 2. Returns token in appropriate format (redirect by default)
|
|
74
|
+
|
|
75
|
+
// This test will be implemented once plugin setup is complete
|
|
76
|
+
expect(true).toBe(true); // Placeholder
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
it("should support response_type=json query parameter", async () => {
|
|
80
|
+
// Test that callback handler:
|
|
81
|
+
// 1. Detects response_type=json in query parameters
|
|
82
|
+
// 2. Returns JSON response with user and token
|
|
83
|
+
// 3. Does not redirect when response_type=json
|
|
84
|
+
|
|
85
|
+
// This test will be implemented once plugin setup is complete
|
|
86
|
+
expect(true).toBe(true); // Placeholder
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
it("should reject callback with invalid state parameter", async () => {
|
|
90
|
+
// Test that callback handler:
|
|
91
|
+
// 1. Detects state mismatch
|
|
92
|
+
// 2. Returns 400 error
|
|
93
|
+
// 3. Prevents CSRF attacks
|
|
94
|
+
|
|
95
|
+
// This test will be implemented once plugin setup is complete
|
|
96
|
+
expect(true).toBe(true); // Placeholder
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
it("should reject callback with missing code parameter", async () => {
|
|
100
|
+
// Test that callback handler:
|
|
101
|
+
// 1. Detects missing authorization code
|
|
102
|
+
// 2. Returns 400 error with clear message
|
|
103
|
+
|
|
104
|
+
// This test will be implemented once plugin setup is complete
|
|
105
|
+
expect(true).toBe(true); // Placeholder
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
it("should handle OAuth provider error (access_denied)", async () => {
|
|
109
|
+
// Test that callback handler:
|
|
110
|
+
// 1. Detects error parameter from provider
|
|
111
|
+
// 2. Maps error to user-friendly message
|
|
112
|
+
// 3. Calls onAuthError callback if provided
|
|
113
|
+
|
|
114
|
+
// This test will be implemented once plugin setup is complete
|
|
115
|
+
expect(true).toBe(true); // Placeholder
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
it("should handle expired or missing session", async () => {
|
|
119
|
+
// Test that callback handler:
|
|
120
|
+
// 1. Detects missing session for state
|
|
121
|
+
// 2. Returns appropriate error message
|
|
122
|
+
// 3. Suggests user try logging in again
|
|
123
|
+
|
|
124
|
+
// This test will be implemented once plugin setup is complete
|
|
125
|
+
expect(true).toBe(true); // Placeholder
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
it("should handle JWT generation failure gracefully", async () => {
|
|
129
|
+
// Test that callback handler:
|
|
130
|
+
// 1. Catches errors from onAuthSuccess callback
|
|
131
|
+
// 2. Logs error securely
|
|
132
|
+
// 3. Calls onAuthError callback if provided
|
|
133
|
+
// 4. Returns user-friendly error message
|
|
134
|
+
|
|
135
|
+
// This test will be implemented once plugin setup is complete
|
|
136
|
+
expect(true).toBe(true); // Placeholder
|
|
137
|
+
});
|
|
107
138
|
});
|
|
108
139
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
// 3. Calls onAuthError callback if provided
|
|
114
|
-
|
|
115
|
-
// This test will be implemented once plugin setup is complete
|
|
116
|
-
expect(true).toBe(true); // Placeholder
|
|
140
|
+
describe("OAuth Flow End-to-End", () => {
|
|
141
|
+
// Note: Full end-to-end tests with mock OAuth provider responses
|
|
142
|
+
// will be added in Task Group 7 by the testing-engineer
|
|
143
|
+
// These placeholder tests establish the test structure
|
|
117
144
|
});
|
|
118
|
-
|
|
119
|
-
it('should handle expired or missing session', async () => {
|
|
120
|
-
// Test that callback handler:
|
|
121
|
-
// 1. Detects missing session for state
|
|
122
|
-
// 2. Returns appropriate error message
|
|
123
|
-
// 3. Suggests user try logging in again
|
|
124
|
-
|
|
125
|
-
// This test will be implemented once plugin setup is complete
|
|
126
|
-
expect(true).toBe(true); // Placeholder
|
|
127
|
-
});
|
|
128
|
-
|
|
129
|
-
it('should handle JWT generation failure gracefully', async () => {
|
|
130
|
-
// Test that callback handler:
|
|
131
|
-
// 1. Catches errors from onAuthSuccess callback
|
|
132
|
-
// 2. Logs error securely
|
|
133
|
-
// 3. Calls onAuthError callback if provided
|
|
134
|
-
// 4. Returns user-friendly error message
|
|
135
|
-
|
|
136
|
-
// This test will be implemented once plugin setup is complete
|
|
137
|
-
expect(true).toBe(true); // Placeholder
|
|
138
|
-
});
|
|
139
|
-
});
|
|
140
|
-
|
|
141
|
-
describe('OAuth Flow End-to-End', () => {
|
|
142
|
-
// Note: Full end-to-end tests with mock OAuth provider responses
|
|
143
|
-
// will be added in Task Group 7 by the testing-engineer
|
|
144
|
-
// These placeholder tests establish the test structure
|
|
145
|
-
});
|
|
146
145
|
});
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* Route: GET /oauth/:provider/callback?code=...&state=...&response_type=json
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
|
-
import { GetHandler, RouteProps, badRequest, internalServerError, log } from "@flink-app/flink";
|
|
15
|
+
import { GetHandler, HttpMethod, RouteProps, badRequest, internalServerError, log } from "@flink-app/flink";
|
|
16
16
|
import CallbackRequest from "../schemas/CallbackRequest";
|
|
17
17
|
import { validateState } from "../utils/state-utils";
|
|
18
18
|
import { getProvider } from "../providers/ProviderRegistry";
|
|
@@ -35,6 +35,7 @@ interface PathParams {
|
|
|
35
35
|
*/
|
|
36
36
|
export const Route: RouteProps = {
|
|
37
37
|
path: "/oauth/:provider/callback",
|
|
38
|
+
method: HttpMethod.get,
|
|
38
39
|
};
|
|
39
40
|
|
|
40
41
|
/**
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* Route: GET /oauth/:provider/initiate?redirectUri={optional_redirect_url}
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
|
-
import { GetHandler, RouteProps, badRequest, internalServerError } from "@flink-app/flink";
|
|
14
|
+
import { GetHandler, HttpMethod, RouteProps, badRequest, internalServerError } from "@flink-app/flink";
|
|
15
15
|
import InitiateRequest from "../schemas/InitiateRequest";
|
|
16
16
|
import { generateState, generateSessionId } from "../utils/state-utils";
|
|
17
17
|
import { getProvider } from "../providers/ProviderRegistry";
|
|
@@ -32,6 +32,7 @@ interface PathParams {
|
|
|
32
32
|
*/
|
|
33
33
|
export const Route: RouteProps = {
|
|
34
34
|
path: "/oauth/:provider/initiate",
|
|
35
|
+
method: HttpMethod.get,
|
|
35
36
|
};
|
|
36
37
|
|
|
37
38
|
/**
|