diff --git a/modules/auth/controllers/auth.controller.js b/modules/auth/controllers/auth.controller.js index 91ed5f3d5..933f90afa 100644 --- a/modules/auth/controllers/auth.controller.js +++ b/modules/auth/controllers/auth.controller.js @@ -207,6 +207,21 @@ const oauthCallback = async (req, res, next) => { })(req, res, next); }; +/** + * @desc Endpoint to expose public auth sign-in/up feature flags + * @param {Object} req - Express request object + * @param {Object} res - Express response object + * @returns {void} Sends the public auth configuration (sign flags only) in the HTTP response + */ +const getConfig = (_req, res) => { + responses.success(res, 'Auth config')({ + sign: { + in: !!config.sign.in, + up: !!config.sign.up, + }, + }); +}; + export default { signup, signin, @@ -214,4 +229,5 @@ export default { oauthCall, oauthCallback, checkOAuthUserProfile, + getConfig, }; diff --git a/modules/auth/routes/auth.routes.js b/modules/auth/routes/auth.routes.js index 73fde70a1..f585bf1bd 100644 --- a/modules/auth/routes/auth.routes.js +++ b/modules/auth/routes/auth.routes.js @@ -13,6 +13,9 @@ import authPassword from '../controllers/auth.password.controller.js'; export default (app) => { const authLimiter = rateLimit(config.rateLimit.auth); + // Public auth config (no authentication required, rate-limited) + app.route('/api/auth/config').get(authLimiter, auth.getConfig); + // Setting up the users password api app.route('/api/auth/forgot').post(authLimiter, authPassword.forgot); app.route('/api/auth/reset/:token').get(authLimiter, authPassword.validateResetToken); diff --git a/modules/auth/tests/auth.integration.tests.js b/modules/auth/tests/auth.integration.tests.js index d33ea74e7..4bf1cfd0f 100644 --- a/modules/auth/tests/auth.integration.tests.js +++ b/modules/auth/tests/auth.integration.tests.js @@ -804,6 +804,34 @@ describe('Auth integration tests:', () => { }); }); + describe('Config endpoint', () => { + test('should return sign flags reflecting current config', async () => { + const result = await agent.get('/api/auth/config').expect(200); + expect(result.body.data).toEqual({ + sign: { + in: expect.any(Boolean), + up: expect.any(Boolean), + }, + }); + }); + + test('should return false when sign.up is disabled', async () => { + const original = config.sign.up; + config.sign.up = false; + const result = await agent.get('/api/auth/config').expect(200); + expect(result.body.data.sign.up).toBe(false); + config.sign.up = original; + }); + + test('should return false when sign.in is disabled', async () => { + const original = config.sign.in; + config.sign.in = false; + const result = await agent.get('/api/auth/config').expect(200); + expect(result.body.data.sign.in).toBe(false); + config.sign.in = original; + }); + }); + // Mongoose disconnect afterAll(async () => { try {