mirror of
				https://github.com/strapi/strapi.git
				synced 2025-10-31 01:47:13 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			546 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			546 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| 'use strict';
 | |
| 
 | |
| // Helpers.
 | |
| const { createAuthRequest } = require('api-tests/request');
 | |
| const { createStrapiInstance, superAdmin } = require('api-tests/strapi');
 | |
| const { createUtils } = require('api-tests/utils');
 | |
| 
 | |
| const internals = {
 | |
|   role: null,
 | |
| };
 | |
| 
 | |
| describe('Admin Auth End to End', () => {
 | |
|   let rq;
 | |
|   let strapi;
 | |
|   let utils;
 | |
| 
 | |
|   beforeAll(async () => {
 | |
|     strapi = await createStrapiInstance();
 | |
|     rq = await createAuthRequest({ strapi });
 | |
|     utils = createUtils(strapi);
 | |
| 
 | |
|     internals.role = await utils.createRole({
 | |
|       name: 'auth_test_role',
 | |
|       description: 'Only used for auth crud test (api)',
 | |
|     });
 | |
|   });
 | |
| 
 | |
|   afterAll(async () => {
 | |
|     await utils.deleteRolesById([internals.role.id]);
 | |
| 
 | |
|     await strapi.destroy();
 | |
|   });
 | |
| 
 | |
|   describe('Login', () => {
 | |
|     test('Can connect successfully', async () => {
 | |
|       const res = await rq({
 | |
|         url: '/admin/login',
 | |
|         method: 'POST',
 | |
|         body: superAdmin.loginInfo,
 | |
|       });
 | |
| 
 | |
|       expect(res.statusCode).toBe(200);
 | |
|       expect(res.body.data).toMatchObject({
 | |
|         token: expect.any(String),
 | |
|         user: {
 | |
|           firstname: expect.stringOrNull(),
 | |
|           lastname: expect.stringOrNull(),
 | |
|           username: expect.stringOrNull(),
 | |
|           email: expect.any(String),
 | |
|           isActive: expect.any(Boolean),
 | |
|         },
 | |
|       });
 | |
|     });
 | |
| 
 | |
|     test('Fails on invalid password', async () => {
 | |
|       const res = await rq({
 | |
|         url: '/admin/login',
 | |
|         method: 'POST',
 | |
|         body: {
 | |
|           ...superAdmin.loginInfo,
 | |
|           password: 'wrongPassword',
 | |
|         },
 | |
|       });
 | |
| 
 | |
|       expect(res.statusCode).toBe(400);
 | |
|       expect(res.body).toEqual({
 | |
|         data: null,
 | |
|         error: {
 | |
|           status: 400,
 | |
|           name: 'ApplicationError',
 | |
|           message: 'Invalid credentials',
 | |
|           details: {},
 | |
|         },
 | |
|       });
 | |
|     });
 | |
| 
 | |
|     test('Fails on invalid email', async () => {
 | |
|       const res = await rq({
 | |
|         url: '/admin/login',
 | |
|         method: 'POST',
 | |
|         body: {
 | |
|           email: 'non-existent-user@strapi.io',
 | |
|           password: 'pcw123',
 | |
|         },
 | |
|       });
 | |
| 
 | |
|       expect(res.statusCode).toBe(400);
 | |
|       expect(res.body).toEqual({
 | |
|         data: null,
 | |
|         error: {
 | |
|           status: 400,
 | |
|           name: 'ApplicationError',
 | |
|           message: 'Invalid credentials',
 | |
|           details: {},
 | |
|         },
 | |
|       });
 | |
|     });
 | |
| 
 | |
|     test('Fails on missing credentials', async () => {
 | |
|       const res = await rq({
 | |
|         url: '/admin/login',
 | |
|         method: 'POST',
 | |
|         body: {
 | |
|           email: 'non-existent-user@strapi.io',
 | |
|         },
 | |
|       });
 | |
| 
 | |
|       expect(res.statusCode).toBe(400);
 | |
|       expect(res.body).toEqual({
 | |
|         data: null,
 | |
|         error: {
 | |
|           status: 400,
 | |
|           name: 'ApplicationError',
 | |
|           message: 'Missing credentials',
 | |
|           details: {},
 | |
|         },
 | |
|       });
 | |
|     });
 | |
|   });
 | |
| 
 | |
|   describe('Renew token', () => {
 | |
|     test('Renew token', async () => {
 | |
|       const authRes = await rq({
 | |
|         url: '/admin/login',
 | |
|         method: 'POST',
 | |
|         body: superAdmin.loginInfo,
 | |
|       });
 | |
| 
 | |
|       expect(authRes.statusCode).toBe(200);
 | |
|       const { token } = authRes.body.data;
 | |
| 
 | |
|       const res = await rq({
 | |
|         url: '/admin/renew-token',
 | |
|         method: 'POST',
 | |
|         body: {
 | |
|           token,
 | |
|         },
 | |
|       });
 | |
| 
 | |
|       expect(res.statusCode).toBe(200);
 | |
|       expect(res.body.data).toEqual({
 | |
|         token: expect.any(String),
 | |
|       });
 | |
|     });
 | |
| 
 | |
|     test('Fails on invalid token', async () => {
 | |
|       const res = await rq({
 | |
|         url: '/admin/renew-token',
 | |
|         method: 'POST',
 | |
|         body: {
 | |
|           token: 'invalid-token',
 | |
|         },
 | |
|       });
 | |
| 
 | |
|       expect(res.statusCode).toBe(400);
 | |
|       expect(res.body).toEqual({
 | |
|         data: null,
 | |
|         error: {
 | |
|           status: 400,
 | |
|           name: 'ValidationError',
 | |
|           message: 'Invalid token',
 | |
|           details: {},
 | |
|         },
 | |
|       });
 | |
|     });
 | |
| 
 | |
|     test('Fails on missing token', async () => {
 | |
|       const res = await rq({
 | |
|         url: '/admin/renew-token',
 | |
|         method: 'POST',
 | |
|         body: {},
 | |
|       });
 | |
| 
 | |
|       expect(res.statusCode).toBe(400);
 | |
|       expect(res.body).toEqual({
 | |
|         data: null,
 | |
|         error: {
 | |
|           status: 400,
 | |
|           message: 'token is a required field',
 | |
|           name: 'ValidationError',
 | |
|           details: {
 | |
|             errors: [
 | |
|               {
 | |
|                 message: 'token is a required field',
 | |
|                 name: 'ValidationError',
 | |
|                 path: ['token'],
 | |
|               },
 | |
|             ],
 | |
|           },
 | |
|         },
 | |
|       });
 | |
|     });
 | |
|   });
 | |
| 
 | |
|   describe('GET /registration-info', () => {
 | |
|     const registrationToken = 'foobar';
 | |
|     let user;
 | |
| 
 | |
|     beforeAll(async () => {
 | |
|       const userInfo = {
 | |
|         email: 'test@strapi.io',
 | |
|         firstname: 'test',
 | |
|         lastname: 'strapi',
 | |
|         roles: [internals.role.id],
 | |
|         registrationToken,
 | |
|         isActive: false,
 | |
|       };
 | |
| 
 | |
|       user = await utils.createUser(userInfo);
 | |
|     });
 | |
| 
 | |
|     afterAll(async () => {
 | |
|       await utils.deleteUserById(user.id);
 | |
|     });
 | |
| 
 | |
|     test('Returns registration info', async () => {
 | |
|       const res = await rq({
 | |
|         url: `/admin/registration-info?registrationToken=${registrationToken}`,
 | |
|         method: 'GET',
 | |
|         body: {},
 | |
|       });
 | |
| 
 | |
|       expect(res.statusCode).toBe(200);
 | |
|       expect(res.body).toEqual({
 | |
|         data: {
 | |
|           email: user.email,
 | |
|           firstname: user.firstname,
 | |
|           lastname: user.lastname,
 | |
|         },
 | |
|       });
 | |
|     });
 | |
| 
 | |
|     test('Fails on missing registration token', async () => {
 | |
|       const res = await rq({
 | |
|         url: '/admin/registration-info',
 | |
|         method: 'GET',
 | |
|         body: {},
 | |
|       });
 | |
| 
 | |
|       expect(res.statusCode).toBe(400);
 | |
|       expect(res.body).toEqual({
 | |
|         data: null,
 | |
|         error: {
 | |
|           status: 400,
 | |
|           details: {
 | |
|             errors: [
 | |
|               {
 | |
|                 message: 'registrationToken is a required field',
 | |
|                 name: 'ValidationError',
 | |
|                 path: ['registrationToken'],
 | |
|               },
 | |
|             ],
 | |
|           },
 | |
|           message: 'registrationToken is a required field',
 | |
|           name: 'ValidationError',
 | |
|         },
 | |
|       });
 | |
|     });
 | |
| 
 | |
|     test('Fails on invalid registration token. Without too much info', async () => {
 | |
|       const res = await rq({
 | |
|         url: '/admin/registration-info?registrationToken=ABCD',
 | |
|         method: 'GET',
 | |
|         body: {},
 | |
|       });
 | |
| 
 | |
|       expect(res.statusCode).toBe(400);
 | |
|       expect(res.body).toEqual({
 | |
|         data: null,
 | |
|         error: {
 | |
|           status: 400,
 | |
|           name: 'ValidationError',
 | |
|           message: 'Invalid registrationToken',
 | |
|           details: {},
 | |
|         },
 | |
|       });
 | |
|     });
 | |
|   });
 | |
| 
 | |
|   describe('GET /register', () => {
 | |
|     let user;
 | |
| 
 | |
|     beforeEach(async () => {
 | |
|       const userInfo = {
 | |
|         email: 'test@strapi.io',
 | |
|         firstname: 'test',
 | |
|         lastname: 'strapi',
 | |
|         registrationToken: 'foobar',
 | |
|       };
 | |
| 
 | |
|       user = await utils.createUser(userInfo);
 | |
|     });
 | |
| 
 | |
|     afterEach(async () => {
 | |
|       await utils.deleteUserById(user.id);
 | |
|     });
 | |
| 
 | |
|     test('Fails on missing payload', async () => {
 | |
|       const res = await rq({
 | |
|         url: '/admin/register',
 | |
|         method: 'POST',
 | |
|         body: {
 | |
|           userInfo: {},
 | |
|         },
 | |
|       });
 | |
| 
 | |
|       expect(res.statusCode).toBe(400);
 | |
|       expect(res.body).toEqual({
 | |
|         data: null,
 | |
|         error: {
 | |
|           status: 400,
 | |
|           details: {
 | |
|             errors: [
 | |
|               {
 | |
|                 message: 'registrationToken is a required field',
 | |
|                 name: 'ValidationError',
 | |
|                 path: ['registrationToken'],
 | |
|               },
 | |
|               {
 | |
|                 message: 'userInfo.firstname is a required field',
 | |
|                 name: 'ValidationError',
 | |
|                 path: ['userInfo', 'firstname'],
 | |
|               },
 | |
|               {
 | |
|                 message: 'userInfo.password is a required field',
 | |
|                 name: 'ValidationError',
 | |
|                 path: ['userInfo', 'password'],
 | |
|               },
 | |
|             ],
 | |
|           },
 | |
|           message: '3 errors occurred',
 | |
|           name: 'ValidationError',
 | |
|         },
 | |
|       });
 | |
|     });
 | |
| 
 | |
|     test('Fails on invalid password', async () => {
 | |
|       const res = await rq({
 | |
|         url: '/admin/register',
 | |
|         method: 'POST',
 | |
|         body: {
 | |
|           registrationToken: user.registrationToken,
 | |
|           userInfo: {
 | |
|             firstname: 'test',
 | |
|             lastname: 'Strapi',
 | |
|             password: '123',
 | |
|           },
 | |
|         },
 | |
|       });
 | |
| 
 | |
|       expect(res.statusCode).toBe(400);
 | |
|       expect(res.body).toEqual({
 | |
|         data: null,
 | |
|         error: {
 | |
|           status: 400,
 | |
|           details: {
 | |
|             errors: [
 | |
|               {
 | |
|                 message: 'userInfo.password must be at least 8 characters',
 | |
|                 name: 'ValidationError',
 | |
|                 path: ['userInfo', 'password'],
 | |
|               },
 | |
|               {
 | |
|                 message: 'userInfo.password must contain at least one lowercase character',
 | |
|                 name: 'ValidationError',
 | |
|                 path: ['userInfo', 'password'],
 | |
|               },
 | |
|               {
 | |
|                 message: 'userInfo.password must contain at least one uppercase character',
 | |
|                 name: 'ValidationError',
 | |
|                 path: ['userInfo', 'password'],
 | |
|               },
 | |
|             ],
 | |
|           },
 | |
|           message: '3 errors occurred',
 | |
|           name: 'ValidationError',
 | |
|         },
 | |
|       });
 | |
|     });
 | |
| 
 | |
|     test('Registers user correctly', async () => {
 | |
|       const userRegistrationInfo = {
 | |
|         firstname: 'test',
 | |
|         lastname: 'Strapi',
 | |
|         password: '1Test2azda3',
 | |
|       };
 | |
| 
 | |
|       const res = await rq({
 | |
|         url: '/admin/register',
 | |
|         method: 'POST',
 | |
|         body: {
 | |
|           registrationToken: user.registrationToken,
 | |
|           userInfo: userRegistrationInfo,
 | |
|         },
 | |
|       });
 | |
| 
 | |
|       expect(res.statusCode).toBe(200);
 | |
|       expect(res.body.data).toMatchObject({
 | |
|         token: expect.any(String),
 | |
|         user: {
 | |
|           email: user.email,
 | |
|           firstname: 'test',
 | |
|           lastname: 'Strapi',
 | |
|         },
 | |
|       });
 | |
| 
 | |
|       expect(res.body.data.user.password === userRegistrationInfo.password).toBe(false);
 | |
|     });
 | |
|   });
 | |
| 
 | |
|   describe('GET /register-admin', () => {
 | |
|     test('Fails on missing payload', async () => {
 | |
|       const res = await rq({
 | |
|         url: '/admin/register-admin',
 | |
|         method: 'POST',
 | |
|         body: {},
 | |
|       });
 | |
| 
 | |
|       expect(res.statusCode).toBe(400);
 | |
|       expect(res.body).toEqual({
 | |
|         data: null,
 | |
|         error: {
 | |
|           status: 400,
 | |
|           details: {
 | |
|             errors: [
 | |
|               {
 | |
|                 message: 'email is a required field',
 | |
|                 name: 'ValidationError',
 | |
|                 path: ['email'],
 | |
|               },
 | |
|               {
 | |
|                 message: 'firstname is a required field',
 | |
|                 name: 'ValidationError',
 | |
|                 path: ['firstname'],
 | |
|               },
 | |
|               {
 | |
|                 message: 'password is a required field',
 | |
|                 name: 'ValidationError',
 | |
|                 path: ['password'],
 | |
|               },
 | |
|             ],
 | |
|           },
 | |
|           message: '3 errors occurred',
 | |
|           name: 'ValidationError',
 | |
|         },
 | |
|       });
 | |
|     });
 | |
| 
 | |
|     test('Fails on invalid password', async () => {
 | |
|       const res = await rq({
 | |
|         url: '/admin/register-admin',
 | |
|         method: 'POST',
 | |
|         body: {
 | |
|           email: 'test@strapi.io',
 | |
|           firstname: 'test',
 | |
|           lastname: 'Strapi',
 | |
|           password: '123',
 | |
|         },
 | |
|       });
 | |
| 
 | |
|       expect(res.statusCode).toBe(400);
 | |
|       expect(res.body).toEqual({
 | |
|         data: null,
 | |
|         error: {
 | |
|           status: 400,
 | |
|           details: {
 | |
|             errors: [
 | |
|               {
 | |
|                 message: 'password must be at least 8 characters',
 | |
|                 name: 'ValidationError',
 | |
|                 path: ['password'],
 | |
|               },
 | |
|               {
 | |
|                 message: 'password must contain at least one lowercase character',
 | |
|                 name: 'ValidationError',
 | |
|                 path: ['password'],
 | |
|               },
 | |
|               {
 | |
|                 message: 'password must contain at least one uppercase character',
 | |
|                 name: 'ValidationError',
 | |
|                 path: ['password'],
 | |
|               },
 | |
|             ],
 | |
|           },
 | |
|           message: '3 errors occurred',
 | |
|           name: 'ValidationError',
 | |
|         },
 | |
|       });
 | |
|     });
 | |
| 
 | |
|     test('Fails if already a user', async () => {
 | |
|       const userInfo = {
 | |
|         email: 'test-admin@strapi.io',
 | |
|         firstname: 'test',
 | |
|         lastname: 'Strapi',
 | |
|         password: '1Test2azda3',
 | |
|       };
 | |
| 
 | |
|       const res = await rq({
 | |
|         url: '/admin/register-admin',
 | |
|         method: 'POST',
 | |
|         body: userInfo,
 | |
|       });
 | |
| 
 | |
|       expect(res.statusCode).toBe(400);
 | |
|       expect(res.body).toEqual({
 | |
|         data: null,
 | |
|         error: {
 | |
|           status: 400,
 | |
|           name: 'ApplicationError',
 | |
|           message: 'You cannot register a new super admin',
 | |
|           details: {},
 | |
|         },
 | |
|       });
 | |
|     });
 | |
|   });
 | |
| 
 | |
|   describe('POST /forgot-password', () => {
 | |
|     test('Always returns en empty response', async () => {
 | |
|       global.strapi.admin.services.auth.forgotPassword = jest.fn(() => {});
 | |
| 
 | |
|       const res = await rq({
 | |
|         url: '/admin/forgot-password',
 | |
|         method: 'POST',
 | |
|         body: {
 | |
|           email: 'admin@strapi.io',
 | |
|         },
 | |
|       });
 | |
| 
 | |
|       expect(res.statusCode).toBe(204);
 | |
|       expect(res.body).toStrictEqual({});
 | |
| 
 | |
|       const nonExistentRes = await rq({
 | |
|         url: '/admin/forgot-password',
 | |
|         method: 'POST',
 | |
|         body: {
 | |
|           email: 'email-do-not-exist@strapi.io',
 | |
|         },
 | |
|       });
 | |
| 
 | |
|       expect(nonExistentRes.statusCode).toBe(204);
 | |
|       expect(nonExistentRes.body).toStrictEqual({});
 | |
|     });
 | |
|   });
 | |
| });
 | 
