110 lines
3.0 KiB
JavaScript
110 lines
3.0 KiB
JavaScript
const assert = require('node:assert/strict');
|
|
const test = require('node:test');
|
|
|
|
const {
|
|
createPassengerTelemetryAuthenticator,
|
|
getBearerToken
|
|
} = require('../src/middleware/passengerTelemetryAuth');
|
|
|
|
function createResponse() {
|
|
return {
|
|
statusCode: null,
|
|
body: null,
|
|
status(statusCode) {
|
|
this.statusCode = statusCode;
|
|
return this;
|
|
},
|
|
json(body) {
|
|
this.body = body;
|
|
return this;
|
|
}
|
|
};
|
|
}
|
|
|
|
function createRequest(authorization) {
|
|
return {
|
|
headers: { authorization },
|
|
get(name) {
|
|
return name.toLowerCase() === 'authorization' ? authorization : undefined;
|
|
}
|
|
};
|
|
}
|
|
|
|
test('requires a Bearer token for passenger telemetry', async () => {
|
|
const middleware = createPassengerTelemetryAuthenticator({
|
|
getFirebaseAuth() {
|
|
throw new Error('should not initialize Firebase without a token');
|
|
}
|
|
});
|
|
const res = createResponse();
|
|
|
|
await middleware(createRequest(), res, () => assert.fail('next should not run'));
|
|
|
|
assert.equal(res.statusCode, 401);
|
|
assert.deepEqual(res.body, { error: 'Access token required' });
|
|
});
|
|
|
|
test('accepts a verified Firebase ID token without retaining its UID', async () => {
|
|
let verifiedToken;
|
|
const middleware = createPassengerTelemetryAuthenticator({
|
|
getFirebaseAuth() {
|
|
return {
|
|
async verifyIdToken(token, checkRevoked) {
|
|
verifiedToken = token;
|
|
assert.equal(checkRevoked, true);
|
|
return { uid: 'must-not-be-copied-to-request' };
|
|
}
|
|
};
|
|
}
|
|
});
|
|
const req = createRequest('Bearer firebase-id-token');
|
|
const res = createResponse();
|
|
let advanced = false;
|
|
|
|
await middleware(req, res, () => {
|
|
advanced = true;
|
|
});
|
|
|
|
assert.equal(verifiedToken, 'firebase-id-token');
|
|
assert.equal(advanced, true);
|
|
assert.equal(req.passengerTelemetryAuthenticated, true);
|
|
assert.equal('user' in req, false);
|
|
assert.equal('firebaseUid' in req, false);
|
|
});
|
|
|
|
test('rejects invalid Firebase ID tokens without logging their value', async () => {
|
|
const warnings = [];
|
|
const middleware = createPassengerTelemetryAuthenticator({
|
|
getFirebaseAuth() {
|
|
return {
|
|
async verifyIdToken() {
|
|
const error = new Error('invalid token should not be logged');
|
|
error.code = 'auth/argument-error';
|
|
throw error;
|
|
}
|
|
};
|
|
},
|
|
authLogger: {
|
|
warn(message, metadata) {
|
|
warnings.push({ message, metadata });
|
|
},
|
|
error() {}
|
|
}
|
|
});
|
|
const res = createResponse();
|
|
|
|
await middleware(createRequest('Bearer private-token-value'), res, () => assert.fail('next should not run'));
|
|
|
|
assert.equal(res.statusCode, 403);
|
|
assert.deepEqual(warnings, [{
|
|
message: 'Passenger telemetry token was rejected',
|
|
metadata: { firebaseCode: 'auth/argument-error' }
|
|
}]);
|
|
});
|
|
|
|
test('parses only a complete Bearer authorization value', () => {
|
|
assert.equal(getBearerToken(createRequest('Bearer token')), 'token');
|
|
assert.equal(getBearerToken(createRequest('Basic token')), null);
|
|
assert.equal(getBearerToken(createRequest('Bearer token extra')), null);
|
|
});
|