feat: Add tests for authentication helper
This commit is contained in:
@@ -3,7 +3,7 @@ import jwt from 'jsonwebtoken';
|
||||
import appConfig from '../config/app.js';
|
||||
import User from '../models/user.js';
|
||||
|
||||
const isAuthenticated = rule()(async (_parent, _args, req) => {
|
||||
export const isAuthenticated = async (_parent, _args, req) => {
|
||||
const token = req.headers['authorization'];
|
||||
|
||||
if (token == null) return false;
|
||||
@@ -26,29 +26,32 @@ const isAuthenticated = rule()(async (_parent, _args, req) => {
|
||||
} catch (error) {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const authentication = shield(
|
||||
{
|
||||
Query: {
|
||||
'*': isAuthenticated,
|
||||
getAutomatischInfo: allow,
|
||||
getConfig: allow,
|
||||
getNotifications: allow,
|
||||
healthcheck: allow,
|
||||
listSamlAuthProviders: allow,
|
||||
},
|
||||
Mutation: {
|
||||
'*': isAuthenticated,
|
||||
forgotPassword: allow,
|
||||
login: allow,
|
||||
registerUser: allow,
|
||||
resetPassword: allow,
|
||||
},
|
||||
const isAuthenticatedRule = rule()(isAuthenticated);
|
||||
|
||||
export const authenticationRules = {
|
||||
Query: {
|
||||
'*': isAuthenticatedRule,
|
||||
getAutomatischInfo: allow,
|
||||
getConfig: allow,
|
||||
getNotifications: allow,
|
||||
healthcheck: allow,
|
||||
listSamlAuthProviders: allow,
|
||||
},
|
||||
{
|
||||
allowExternalErrors: true,
|
||||
}
|
||||
);
|
||||
Mutation: {
|
||||
'*': isAuthenticatedRule,
|
||||
forgotPassword: allow,
|
||||
login: allow,
|
||||
registerUser: allow,
|
||||
resetPassword: allow,
|
||||
},
|
||||
};
|
||||
|
||||
export const authenticationOptions = {
|
||||
allowExternalErrors: true,
|
||||
};
|
||||
|
||||
const authentication = shield(authenticationRules, authenticationOptions);
|
||||
|
||||
export default authentication;
|
||||
|
82
packages/backend/src/helpers/authentication.test.js
Normal file
82
packages/backend/src/helpers/authentication.test.js
Normal file
@@ -0,0 +1,82 @@
|
||||
import { describe, it, expect, vi } from 'vitest';
|
||||
import { allow } from 'graphql-shield';
|
||||
import jwt from 'jsonwebtoken';
|
||||
import User from '../models/user.js';
|
||||
import {
|
||||
isAuthenticated,
|
||||
isAuthenticatedRule,
|
||||
authenticationRules,
|
||||
} from './authentication.js';
|
||||
|
||||
vi.mock('jsonwebtoken');
|
||||
vi.mock('../models/user.js');
|
||||
|
||||
describe('isAuthenticated', () => {
|
||||
it('should return false if no token is provided', async () => {
|
||||
const req = { headers: {} };
|
||||
expect(await isAuthenticated(null, null, req)).toBe(false);
|
||||
});
|
||||
|
||||
it('should return false if token is invalid', async () => {
|
||||
jwt.verify.mockImplementation(() => {
|
||||
throw new Error('invalid token');
|
||||
});
|
||||
|
||||
const req = { headers: { authorization: 'invalidToken' } };
|
||||
expect(await isAuthenticated(null, null, req)).toBe(false);
|
||||
});
|
||||
|
||||
it('should return true if token is valid', async () => {
|
||||
jwt.verify.mockReturnValue({ userId: '123' });
|
||||
|
||||
User.query.mockReturnValue({
|
||||
findById: vi.fn().mockReturnValue({
|
||||
leftJoinRelated: vi.fn().mockReturnThis(),
|
||||
withGraphFetched: vi
|
||||
.fn()
|
||||
.mockResolvedValue({ id: '123', role: {}, permissions: {} }),
|
||||
}),
|
||||
});
|
||||
|
||||
const req = { headers: { authorization: 'validToken' } };
|
||||
expect(await isAuthenticated(null, null, req)).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('authentication rules', () => {
|
||||
const getQueryAndMutationNames = (rules) => {
|
||||
const queries = Object.keys(rules.Query || {});
|
||||
const mutations = Object.keys(rules.Mutation || {});
|
||||
return { queries, mutations };
|
||||
};
|
||||
|
||||
const { queries, mutations } = getQueryAndMutationNames(authenticationRules);
|
||||
|
||||
describe('for queries', () => {
|
||||
queries.forEach((query) => {
|
||||
it(`should apply correct rule for query: ${query}`, () => {
|
||||
const ruleApplied = authenticationRules.Query[query];
|
||||
|
||||
if (query === '*') {
|
||||
expect(ruleApplied.func).toBe(isAuthenticated);
|
||||
} else {
|
||||
expect(ruleApplied).toEqual(allow);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('for mutations', () => {
|
||||
mutations.forEach((mutation) => {
|
||||
it(`should apply correct rule for mutation: ${mutation}`, () => {
|
||||
const ruleApplied = authenticationRules.Mutation[mutation];
|
||||
|
||||
if (mutation === '*') {
|
||||
expect(ruleApplied.func).toBe(isAuthenticated);
|
||||
} else {
|
||||
expect(ruleApplied).toBe(allow);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
Reference in New Issue
Block a user