diff --git a/packages/gitlab-backend/src/service/router.test.ts b/packages/gitlab-backend/src/service/router.test.ts index 04a3f845..a4b91bb2 100644 --- a/packages/gitlab-backend/src/service/router.test.ts +++ b/packages/gitlab-backend/src/service/router.test.ts @@ -7,9 +7,8 @@ import { setupServer } from 'msw/node'; import { createRouter } from './router'; -describe('createRouter', () => { - let app: express.Application; - const server = setupServer( +const buildServer = () => { + return setupServer( rest.get( 'https://non-existing-example.com/api/v4/projects/434', (req, res, ctx) => { @@ -59,6 +58,14 @@ describe('createRouter', () => { } ) ); +}; + +describe('createRouter', () => { + let app: express.Application; + const server = buildServer(); + + const token = 'Bearer iT6P7Ikla2zgBfGSPEWps'; + const token2 = `${token}other`; const config = new ConfigReader({ integrations: { @@ -66,10 +73,12 @@ describe('createRouter', () => { { host: 'non-existing-example.com', apiBaseUrl: 'https://non-existing-example.com/api/v4', + token, }, { host: 'non-existing-example-2.com', apiBaseUrl: 'https://non-existing-example-2.com/api/v4', + token: token2, }, ], }, @@ -113,6 +122,7 @@ describe('createRouter', () => { connection: 'close', host: 'non-existing-example.com', 'user-agent': 'supertest', + 'private-token': token, }, url: 'https://non-existing-example.com/api/v4/projects/434', }); @@ -132,6 +142,7 @@ describe('createRouter', () => { connection: 'close', host: 'non-existing-example-2.com', 'user-agent': 'supertest', + 'private-token': token2, }, url: 'https://non-existing-example-2.com/api/v4/projects/434', }); @@ -155,6 +166,7 @@ describe('createRouter', () => { 'content-type': 'application/json', host: 'non-existing-example.com', 'user-agent': 'supertest', + 'private-token': token, }, url: 'https://non-existing-example.com/api/graphql', }); @@ -176,6 +188,7 @@ describe('createRouter', () => { 'content-type': 'application/json', host: 'non-existing-example-2.com', 'user-agent': 'supertest', + 'private-token': token2, }, url: 'https://non-existing-example-2.com/api/graphql', }); @@ -256,56 +269,7 @@ describe('createRouter', () => { describe('createRouter with baseUrl', () => { let app: express.Application; - const server = setupServer( - rest.get( - 'https://non-existing-example.com/api/v4/projects/434', - (req, res, ctx) => { - return res( - ctx.status(200), - ctx.json({ - url: req.url.toString(), - headers: req.headers.all(), - }) - ); - } - ), - rest.get( - 'https://non-existing-example-2.com/api/v4/projects/434', - (req, res, ctx) => { - return res( - ctx.status(200), - ctx.json({ - url: req.url.toString(), - headers: req.headers.all(), - }) - ); - } - ), - rest.post( - 'https://non-existing-example.com/api/graphql', - (req, res, ctx) => { - return res( - ctx.status(200), - ctx.json({ - url: req.url.toString(), - headers: req.headers.all(), - }) - ); - } - ), - rest.post( - 'https://non-existing-example-2.com/api/graphql', - (req, res, ctx) => { - return res( - ctx.status(200), - ctx.json({ - url: req.url.toString(), - headers: req.headers.all(), - }) - ); - } - ) - ); + const server = buildServer(); const basePath = '/docs'; @@ -517,3 +481,117 @@ describe('createRouter with baseUrl', () => { }); }); }); + +describe('OAuth token authorizations', () => { + let app: express.Application; + const OAuthToken = 'Bearer iT6P7Ikla2zgBfGSPEWps'; + const server = setupServer( + rest.get( + 'https://example-gitlab.com/api/v4/projects/434', + (req, res, ctx) => { + return res( + ctx.status(200), + ctx.json({ + url: req.url.toString(), + headers: req.headers.all(), + }) + ); + } + ), + rest.post('https://example-gitlab.com/api/graphql', (req, res, ctx) => { + return res( + ctx.status(200), + ctx.json({ + url: req.url.toString(), + headers: req.headers.all(), + }) + ); + }) + ); + + const config = new ConfigReader({ + gitlab: { + useOAuth: true, + }, + integrations: { + gitlab: [ + { + host: 'example-gitlab.com', + apiBaseUrl: 'https://example-gitlab.com/api/v4', + token: 'Bearer different-from-oauth', + }, + ], + }, + }); + + beforeAll(async () => { + const router = await createRouter({ + logger: getVoidLogger(), + config, + }); + app = express().use('/api/gitlab', router); + server.listen({ + onUnhandledRequest: ({ headers }, print) => { + if (headers.get('User-Agent') === 'supertest') { + return; + } + print.error(); + }, + }); + }); + + afterAll(() => server.close()); + + beforeEach(async () => { + jest.resetAllMocks(); + server.resetHandlers(); + }); + + describe('GET Request', () => { + it('Oauth Token should work', async () => { + const agent = request.agent(app); + // this is set to let msw pass test requests through the mock server + agent.set('User-Agent', 'supertest'); + agent.set('gitlab-authorization', OAuthToken); + const response = await agent.get( + '/api/gitlab/rest/example-gitlab.com/projects/434' + ); + expect(response.status).toEqual(200); + expect(response.body).toEqual({ + headers: { + 'accept-encoding': 'gzip, deflate', + connection: 'close', + host: 'example-gitlab.com', + 'user-agent': 'supertest', + authorization: OAuthToken, + }, + url: 'https://example-gitlab.com/api/v4/projects/434', + }); + }); + }); + + describe('Graphql requests', () => { + it('Oauth Token should work', async () => { + const agent = request.agent(app); + // this is set to let msw pass test requests through the mock server + agent.set('User-Agent', 'supertest'); + agent.set('gitlab-authorization', OAuthToken); + const response = await agent.post( + '/api/gitlab/graphql/example-gitlab.com' + ); + expect(response.status).toEqual(200); + expect(response.body).toEqual({ + headers: { + 'accept-encoding': 'gzip, deflate', + connection: 'close', + 'content-length': '2', + 'content-type': 'application/json', + host: 'example-gitlab.com', + 'user-agent': 'supertest', + authorization: OAuthToken, + }, + url: 'https://example-gitlab.com/api/graphql', + }); + }); + }); +}); diff --git a/packages/gitlab-backend/src/service/router.ts b/packages/gitlab-backend/src/service/router.ts index e07adf77..adef0da1 100644 --- a/packages/gitlab-backend/src/service/router.ts +++ b/packages/gitlab-backend/src/service/router.ts @@ -51,20 +51,24 @@ export async function createRouter( const filter = (_pathname: string, req: Request): boolean => { if (req.headers['authorization']) delete req.headers['authorization']; // Forward authorization, this header is defined when gitlab.useOAuth is true - if (req.headers['gitlab-authorization']) + if (req.headers['gitlab-authorization']) { req.headers['authorization'] = req.headers[ 'gitlab-authorization' ] as string; + delete req.headers['gitlab-authorization']; + } return req.method === 'GET'; }; const graphqlFilter = (_pathname: string, req: Request): boolean => { if (req.headers['authorization']) delete req.headers['authorization']; // Forward authorization, this header is defined when gitlab.useOAuth is true - if (req.headers['gitlab-authorization']) + if (req.headers['gitlab-authorization']) { req.headers['authorization'] = req.headers[ 'gitlab-authorization' ] as string; + delete req.headers['gitlab-authorization']; + } return req.method === 'POST' && !req.body.query?.includes('mutation'); };