Files
overleaf-cep/services/history-v1/test/acceptance/js/api/auth.test.js
T
Anna Claire Fields 65c164c73d Merge pull request #30053 from overleaf/acf-migration4-controllers-and-params
(4) Update controllers and tests for Zod migration

GitOrigin-RevId: 876fd64f96e1f5d7244ac1d45053c7db9857d46b
2025-12-16 09:06:44 +00:00

174 lines
5.1 KiB
JavaScript

const config = require('config')
const sinon = require('sinon')
const { expect } = require('chai')
const nodeFetch = require('node-fetch')
const cleanup = require('../storage/support/cleanup')
const expectResponse = require('./support/expect_response')
const fixtures = require('../storage/support/fixtures')
const testServer = require('./support/test_server')
describe('auth', function () {
beforeEach(cleanup.everything)
beforeEach(fixtures.create)
beforeEach('Set up stubs', function () {
sinon.stub(config, 'has').callThrough()
sinon.stub(config, 'get').callThrough()
})
afterEach(sinon.restore)
it('protects /docs with basic auth', async function () {
const url = testServer.url('/docs')
const unauthenticatedResponse = await nodeFetch(url)
expect(unauthenticatedResponse.status).to.equal(401)
expect(unauthenticatedResponse.headers.get('www-authenticate')).to.match(
/^Basic/
)
const badHeader =
'Basic ' + Buffer.from('staging:wrong-password').toString('base64')
const badPasswordResponse = await nodeFetch(url, {
headers: { Authorization: badHeader },
})
expect(badPasswordResponse.status).to.equal(401)
const validResponse = await nodeFetch(url, {
headers: { Authorization: testServer.basicAuthHeader },
})
expect(validResponse.status).to.equal(200)
})
it('renders 401 on ProjectImport endpoints', async function () {
const unauthenticatedClient = testServer.client
try {
await unauthenticatedClient.apis.ProjectImport.importSnapshot1({
project_id: '1',
snapshot: { files: {} },
})
expect.fail()
} catch (err) {
expectResponse.unauthorized(err)
expect(err.response.headers['www-authenticate']).to.match(/^Basic/)
}
// check that the snapshot was not persisted even if the response was a 401
const projectClient = await testServer.createClientForProject('1')
try {
await projectClient.apis.Project.getLatestHistory({ project_id: '1' })
expect.fail()
} catch (err) {
expectResponse.notFound(err)
}
})
it('renders 401 for JWT endpoints', function () {
return testServer.client.apis.Project.getLatestHistory({
project_id: '10000',
})
.then(() => {
expect.fail()
})
.catch(err => {
expectResponse.unauthorized(err)
expect(err.response.headers['www-authenticate']).to.equal('Bearer')
})
})
it('accepts basic auth in place of JWT (for now)', function () {
const projectId = fixtures.docs.initializedProject.id
return testServer.pseudoJwtBasicAuthClient.apis.Project.getLatestHistory({
project_id: projectId,
}).then(response => {
expect(response.obj.chunk).to.exist
})
})
it('uses JWT', function () {
const projectId = fixtures.docs.initializedProject.id
return testServer
.createClientForProject(projectId)
.then(client => {
return client.apis.Project.getLatestHistory({
project_id: projectId,
})
})
.then(response => {
expect(response.obj.chunk).to.exist
})
})
it('checks for project id', function () {
return testServer
.createClientForProject('1')
.then(client => {
return client.apis.Project.getLatestHistory({
project_id: '2',
})
})
.then(() => {
expect.fail()
})
.catch(expectResponse.forbidden)
})
it('does not accept jwt for ProjectUpdate endpoints', function () {
return testServer.createClientForProject('1').then(client => {
return client.apis.ProjectImport.importSnapshot1({
project_id: '1',
snapshot: {},
})
.then(() => {
expect.fail()
})
.catch(expectResponse.unauthorized)
})
})
describe('when an old JWT key is defined', function () {
beforeEach(function () {
setMockConfig('jwtAuth.oldKey', 'old-secret')
})
it('accepts the old key', async function () {
const projectId = fixtures.docs.initializedProject.id
const client = await testServer.createClientForProject(projectId, {
jwtKey: 'old-secret',
})
const response = await client.apis.Project.getLatestHistory({
project_id: projectId,
})
expect(response.obj.chunk).to.exist
})
it('accepts the new key', async function () {
const projectId = fixtures.docs.initializedProject.id
const client = await testServer.createClientForProject(projectId)
const response = await client.apis.Project.getLatestHistory({
project_id: projectId,
})
expect(response.obj.chunk).to.exist
})
it('rejects other keys', async function () {
const projectId = fixtures.docs.initializedProject.id
const client = await testServer.createClientForProject(projectId, {
jwtKey: 'bad-secret',
})
try {
await client.apis.Project.getLatestHistory({
project_id: projectId,
})
expect.fail()
} catch (err) {
expectResponse.unauthorized(err)
}
})
})
})
function setMockConfig(path, value) {
config.has.withArgs(path).returns(true)
config.get.withArgs(path).returns(value)
}