| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356 |
- /* eslint-disable arrow-body-style */
- const { getInstance } = require('../setup-crowi');
- describe('loginRequired', () => {
- let crowi;
- const fallbackMock = jest.fn().mockReturnValue('fallback');
- let loginRequiredStrictly;
- let loginRequired;
- let loginRequiredWithFallback;
- beforeEach(async () => {
- crowi = await getInstance();
- loginRequiredStrictly = require('~/server/middlewares/login-required')(
- crowi,
- );
- loginRequired = require('~/server/middlewares/login-required')(crowi, true);
- loginRequiredWithFallback = require('~/server/middlewares/login-required')(
- crowi,
- false,
- fallbackMock,
- );
- });
- describe('not strict mode', () => {
- const res = {
- redirect: jest.fn().mockReturnValue('redirect'),
- sendStatus: jest.fn().mockReturnValue('sendStatus'),
- };
- const next = jest.fn().mockReturnValue('next');
- describe('and when aclService.isGuestAllowedToRead() returns false', () => {
- let req;
- let isGuestAllowedToReadSpy;
- beforeEach(async () => {
- // setup req
- req = {
- originalUrl: 'original url 1',
- session: {},
- };
- // reset session object
- req.session = {};
- // prepare spy for AclService.isGuestAllowedToRead
- isGuestAllowedToReadSpy = jest
- .spyOn(crowi.aclService, 'isGuestAllowedToRead')
- .mockImplementation(() => false);
- });
- /* eslint-disable indent */
- test.each`
- userStatus | expectedPath
- ${1} | ${'/login/error/registered'}
- ${3} | ${'/login/error/suspended'}
- ${5} | ${'/invited'}
- `(
- "redirect to '$expectedPath' when user.status is '$userStatus'",
- ({ userStatus, expectedPath }) => {
- req.user = {
- _id: 'user id',
- status: userStatus,
- };
- const result = loginRequired(req, res, next);
- expect(isGuestAllowedToReadSpy).not.toHaveBeenCalled();
- expect(next).not.toHaveBeenCalled();
- expect(fallbackMock).not.toHaveBeenCalled();
- expect(res.sendStatus).not.toHaveBeenCalled();
- expect(res.redirect).toHaveBeenCalledTimes(1);
- expect(res.redirect).toHaveBeenCalledWith(expectedPath);
- expect(result).toBe('redirect');
- expect(req.session.redirectTo).toBe(undefined);
- },
- );
- /* eslint-disable indent */
- test("redirect to '/login' when the user does not loggedin", () => {
- req.baseUrl = '/path/that/requires/loggedin';
- const result = loginRequired(req, res, next);
- expect(isGuestAllowedToReadSpy).toHaveBeenCalled();
- expect(next).not.toHaveBeenCalled();
- expect(fallbackMock).not.toHaveBeenCalled();
- expect(res.sendStatus).not.toHaveBeenCalled();
- expect(res.redirect).toHaveBeenCalledTimes(1);
- expect(res.redirect).toHaveBeenCalledWith('/login');
- expect(result).toBe('redirect');
- expect(req.session.redirectTo).toBe('original url 1');
- });
- test('pass anyone into sharedPage', () => {
- req.isSharedPage = true;
- const result = loginRequired(req, res, next);
- expect(isGuestAllowedToReadSpy).toHaveBeenCalled();
- expect(fallbackMock).not.toHaveBeenCalled();
- expect(res.sendStatus).not.toHaveBeenCalled();
- expect(next).toHaveBeenCalled();
- expect(res.redirect).not.toHaveBeenCalled();
- expect(result).toBe('next');
- });
- });
- describe('and when aclService.isGuestAllowedToRead() returns true', () => {
- let req;
- let isGuestAllowedToReadSpy;
- beforeEach(async () => {
- // setup req
- req = {
- originalUrl: 'original url 1',
- session: {},
- };
- // reset session object
- req.session = {};
- // prepare spy for AclService.isGuestAllowedToRead
- isGuestAllowedToReadSpy = jest
- .spyOn(crowi.aclService, 'isGuestAllowedToRead')
- .mockImplementation(() => true);
- });
- /* eslint-disable indent */
- test.each`
- userStatus | expectedPath
- ${1} | ${'/login/error/registered'}
- ${3} | ${'/login/error/suspended'}
- ${5} | ${'/invited'}
- `(
- "redirect to '$expectedPath' when user.status is '$userStatus'",
- ({ userStatus, expectedPath }) => {
- req.user = {
- _id: 'user id',
- status: userStatus,
- };
- const result = loginRequired(req, res, next);
- expect(isGuestAllowedToReadSpy).not.toHaveBeenCalled();
- expect(next).not.toHaveBeenCalled();
- expect(fallbackMock).not.toHaveBeenCalled();
- expect(res.sendStatus).not.toHaveBeenCalled();
- expect(res.redirect).toHaveBeenCalledTimes(1);
- expect(res.redirect).toHaveBeenCalledWith(expectedPath);
- expect(result).toBe('redirect');
- expect(req.session.redirectTo).toBe(undefined);
- },
- );
- /* eslint-disable indent */
- test('pass guest user', () => {
- const result = loginRequired(req, res, next);
- expect(isGuestAllowedToReadSpy).toHaveBeenCalledTimes(1);
- expect(fallbackMock).not.toHaveBeenCalled();
- expect(res.sendStatus).not.toHaveBeenCalled();
- expect(next).toHaveBeenCalled();
- expect(res.redirect).not.toHaveBeenCalled();
- expect(result).toBe('next');
- });
- test('pass anyone into sharedPage', () => {
- req.isSharedPage = true;
- const result = loginRequired(req, res, next);
- expect(isGuestAllowedToReadSpy).toHaveBeenCalled();
- expect(fallbackMock).not.toHaveBeenCalled();
- expect(res.sendStatus).not.toHaveBeenCalled();
- expect(next).toHaveBeenCalled();
- expect(res.redirect).not.toHaveBeenCalled();
- expect(result).toBe('next');
- });
- });
- });
- describe('strict mode', () => {
- // setup req/res/next
- const req = {
- originalUrl: 'original url 1',
- session: null,
- };
- const res = {
- redirect: jest.fn().mockReturnValue('redirect'),
- sendStatus: jest.fn().mockReturnValue('sendStatus'),
- };
- const next = jest.fn().mockReturnValue('next');
- let isGuestAllowedToReadSpy;
- beforeEach(async () => {
- // reset session object
- req.session = {};
- // spy for AclService.isGuestAllowedToRead
- isGuestAllowedToReadSpy = jest.spyOn(
- crowi.aclService,
- 'isGuestAllowedToRead',
- );
- });
- test("send status 403 when 'req.baseUrl' starts with '_api'", () => {
- req.baseUrl = '/_api/someapi';
- const result = loginRequiredStrictly(req, res, next);
- expect(isGuestAllowedToReadSpy).not.toHaveBeenCalled();
- expect(next).not.toHaveBeenCalled();
- expect(fallbackMock).not.toHaveBeenCalled();
- expect(res.redirect).not.toHaveBeenCalled();
- expect(res.sendStatus).toHaveBeenCalledTimes(1);
- expect(res.sendStatus).toHaveBeenCalledWith(403);
- expect(result).toBe('sendStatus');
- });
- test("redirect to '/login' when the user does not loggedin", () => {
- req.baseUrl = '/path/that/requires/loggedin';
- const result = loginRequiredStrictly(req, res, next);
- expect(isGuestAllowedToReadSpy).not.toHaveBeenCalled();
- expect(next).not.toHaveBeenCalled();
- expect(fallbackMock).not.toHaveBeenCalled();
- expect(res.sendStatus).not.toHaveBeenCalled();
- expect(res.redirect).toHaveBeenCalledTimes(1);
- expect(res.redirect).toHaveBeenCalledWith('/login');
- expect(result).toBe('redirect');
- expect(req.session.redirectTo).toBe('original url 1');
- });
- test('pass user who logged in', () => {
- const User = crowi.model('User');
- req.user = {
- _id: 'user id',
- status: User.STATUS_ACTIVE,
- };
- const result = loginRequiredStrictly(req, res, next);
- expect(isGuestAllowedToReadSpy).not.toHaveBeenCalled();
- expect(fallbackMock).not.toHaveBeenCalled();
- expect(res.sendStatus).not.toHaveBeenCalled();
- expect(res.redirect).not.toHaveBeenCalled();
- expect(next).toHaveBeenCalledTimes(1);
- expect(result).toBe('next');
- expect(req.session.redirectTo).toBe(undefined);
- });
- /* eslint-disable indent */
- test.each`
- userStatus | expectedPath
- ${1} | ${'/login/error/registered'}
- ${3} | ${'/login/error/suspended'}
- ${5} | ${'/invited'}
- `(
- "redirect to '$expectedPath' when user.status is '$userStatus'",
- ({ userStatus, expectedPath }) => {
- req.user = {
- _id: 'user id',
- status: userStatus,
- };
- const result = loginRequiredStrictly(req, res, next);
- expect(isGuestAllowedToReadSpy).not.toHaveBeenCalled();
- expect(next).not.toHaveBeenCalled();
- expect(fallbackMock).not.toHaveBeenCalled();
- expect(res.sendStatus).not.toHaveBeenCalled();
- expect(res.redirect).toHaveBeenCalledTimes(1);
- expect(res.redirect).toHaveBeenCalledWith(expectedPath);
- expect(result).toBe('redirect');
- expect(req.session.redirectTo).toBe(undefined);
- },
- );
- /* eslint-disable indent */
- test("redirect to '/login' when user.status is 'STATUS_DELETED'", () => {
- const User = crowi.model('User');
- req.baseUrl = '/path/that/requires/loggedin';
- req.user = {
- _id: 'user id',
- status: User.STATUS_DELETED,
- };
- const result = loginRequiredStrictly(req, res, next);
- expect(isGuestAllowedToReadSpy).not.toHaveBeenCalled();
- expect(next).not.toHaveBeenCalled();
- expect(fallbackMock).not.toHaveBeenCalled();
- expect(res.sendStatus).not.toHaveBeenCalled();
- expect(res.redirect).toHaveBeenCalledTimes(1);
- expect(res.redirect).toHaveBeenCalledWith('/login');
- expect(result).toBe('redirect');
- expect(req.session.redirectTo).toBe(undefined);
- });
- });
- describe('specified fallback', () => {
- // setup req/res/next
- const req = {
- originalUrl: 'original url 1',
- session: null,
- };
- const res = {
- redirect: jest.fn().mockReturnValue('redirect'),
- sendStatus: jest.fn().mockReturnValue('sendStatus'),
- };
- const next = jest.fn().mockReturnValue('next');
- let isGuestAllowedToReadSpy;
- beforeEach(async () => {
- // reset session object
- req.session = {};
- // spy for AclService.isGuestAllowedToRead
- isGuestAllowedToReadSpy = jest.spyOn(
- crowi.aclService,
- 'isGuestAllowedToRead',
- );
- });
- test("invoke fallback when 'req.path' starts with '_api'", () => {
- req.path = '/_api/someapi';
- const result = loginRequiredWithFallback(req, res, next);
- expect(isGuestAllowedToReadSpy).not.toHaveBeenCalled();
- expect(next).not.toHaveBeenCalled();
- expect(res.redirect).not.toHaveBeenCalled();
- expect(res.sendStatus).not.toHaveBeenCalled();
- expect(fallbackMock).toHaveBeenCalledTimes(1);
- expect(fallbackMock).toHaveBeenCalledWith(req, res, next);
- expect(result).toBe('fallback');
- });
- test('invoke fallback when the user does not loggedin', () => {
- req.path = '/path/that/requires/loggedin';
- const result = loginRequiredWithFallback(req, res, next);
- expect(isGuestAllowedToReadSpy).not.toHaveBeenCalled();
- expect(next).not.toHaveBeenCalled();
- expect(res.sendStatus).not.toHaveBeenCalled();
- expect(res.redirect).not.toHaveBeenCalled();
- expect(fallbackMock).toHaveBeenCalledTimes(1);
- expect(fallbackMock).toHaveBeenCalledWith(req, res, next);
- expect(result).toBe('fallback');
- });
- });
- });
|