fix: use supported redirect mode for Workers organization requests
Deploy EG-BIM QA Gateway / deploy (push) Successful in 1m24s
Deploy EG-BIM QA Gateway / deploy (push) Successful in 1m24s
This commit is contained in:
1 parent
c87e0aa0c1
commit
ccf48c8224
8 files changed
+126
-4
No files matched your search
@@ -0,0 +1,50 @@
|
||||
import worker from './index.js';
|
||||
|
||||
const ROOT = '038326b6-954a-48a7-a85f-efd83f62b82a';
|
||||
const USER = '01900000-0000-7000-8000-000000000001';
|
||||
const DEPT = 'ee2f39ac-fe52-4cfb-b4e3-4ae1d114c916';
|
||||
const encoder = new TextEncoder();
|
||||
const encode = (bytes) => btoa(String.fromCharCode(...bytes)).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
|
||||
|
||||
function equal(actual, expected, field) {
|
||||
if (actual !== expected) throw new Error(`${field}: expected ${expected}, received ${actual}`);
|
||||
}
|
||||
|
||||
export default {
|
||||
async test() {
|
||||
const user = {
|
||||
userUuid: USER, ssoSubject: USER, requesterId: USER,
|
||||
tenantId: DEPT, requesterTenantId: DEPT,
|
||||
company: 'IS3', companySource: 'sso', department: ''
|
||||
};
|
||||
const env = {
|
||||
SESSION_COOKIE_NAME: 'fixture_session', SESSION_SECRET: 'fixture-session-secret',
|
||||
ORG_CONTEXT_ENABLED: 'true', ORG_CONTEXT_API_URL: 'https://organization.example.test/org-context',
|
||||
ORG_CONTEXT_KEY_ID: 'fixture-key-id', ORG_CONTEXT_KEY_SECRET: 'fixture-key-secret',
|
||||
ORG_CONTEXT_TENANT_IDS: JSON.stringify([ROOT])
|
||||
};
|
||||
const payload = encode(encoder.encode(JSON.stringify({ user, expiresAt: Date.now() + 60000 })));
|
||||
const key = await crypto.subtle.importKey('raw', encoder.encode(env.SESSION_SECRET), { name: 'HMAC', hash: 'SHA-256' }, false, ['sign']);
|
||||
const signature = encode(new Uint8Array(await crypto.subtle.sign('HMAC', key, encoder.encode(payload))));
|
||||
const request = () => new Request('https://qa.example.test/auth/session', {
|
||||
headers: { cookie: `${env.SESSION_COOKIE_NAME}=${payload}.${signature}` }
|
||||
});
|
||||
|
||||
const response = await worker.fetch(request(), env);
|
||||
const session = await response.json();
|
||||
equal(response.status, 200, 'session HTTP status');
|
||||
equal(session.authenticated, true, 'authenticated');
|
||||
equal(session.user.orgContextStatus, 'resolved', 'organization lookup');
|
||||
equal(session.user.company, '총괄기획실&기술개발센터', 'company');
|
||||
equal(session.user.department, 'IS3', 'department');
|
||||
equal(session.user.requesterId, USER, 'canonical identity');
|
||||
equal(session.user.orgContextError, undefined, 'error after success');
|
||||
|
||||
const rejected = await worker.fetch(request(), {
|
||||
...env, ORG_CONTEXT_API_URL: 'https://organization.example.test/redirect'
|
||||
});
|
||||
const rejectedSession = await rejected.json();
|
||||
equal(rejectedSession.authenticated, true, 'session after upstream redirect');
|
||||
equal(rejectedSession.user.orgContextError, 'org_context_http_302', 'redirect rejection');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,26 @@
|
||||
const ROOT = '038326b6-954a-48a7-a85f-efd83f62b82a';
|
||||
const COMPANY = '9951229e-eea5-4376-96f4-78989bc3a506';
|
||||
const DEPT = 'ee2f39ac-fe52-4cfb-b4e3-4ae1d114c916';
|
||||
const USER = '01900000-0000-7000-8000-000000000001';
|
||||
|
||||
export default {
|
||||
fetch(request) {
|
||||
const url = new URL(request.url);
|
||||
if (url.origin !== 'https://organization.example.test') throw new Error('Redirect must never be followed');
|
||||
if (request.headers.get('X-Baron-Key-ID') !== 'fixture-key-id' || request.headers.get('X-Baron-Key-Secret') !== 'fixture-key-secret') {
|
||||
throw new Error('Expected organization integration credentials');
|
||||
}
|
||||
if (url.pathname === '/redirect') return Response.redirect('https://must-not-follow.example.test/', 302);
|
||||
if (url.searchParams.get('tenantId') !== ROOT || url.searchParams.get('exposure') !== 'identifiers') {
|
||||
throw new Error('Unexpected organization query');
|
||||
}
|
||||
return Response.json({
|
||||
schemaVersion: 'baron.org-context.v2', scope: { tenantId: ROOT },
|
||||
tree: { id: ROOT, name: '한맥가족', type: 'COMPANY_GROUP', children: [
|
||||
{ id: COMPANY, name: '총괄기획실&기술개발센터', type: 'COMPANY', children: [
|
||||
{ id: DEPT, name: 'IS3', type: 'COMPANY', members: [{ id: USER, isPrimary: true }] }
|
||||
] }
|
||||
] }
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,19 @@
|
||||
using Workerd = import "/workerd/workerd.capnp";
|
||||
|
||||
const config :Workerd.Config = (
|
||||
services = [
|
||||
(name = "organization", worker = (
|
||||
compatibilityDate = "2026-09-18",
|
||||
globalOutbound = "organization-upstream",
|
||||
modules = [
|
||||
(name = "test.mjs", esModule = embed "organization-test.mjs"),
|
||||
(name = "index.js", esModule = embed "../../src/index.js"),
|
||||
(name = "org-context.js", esModule = embed "../../src/org-context.js")
|
||||
]
|
||||
)),
|
||||
(name = "organization-upstream", worker = (
|
||||
compatibilityDate = "2026-09-18",
|
||||
modules = [(name = "upstream.mjs", esModule = embed "organization-upstream.mjs")]
|
||||
))
|
||||
]
|
||||
);
|
||||
Reference in new issue
Block a user