Merge branch 'dev' into feature/49-openapi_cookie_schema
	
		
			
	
		
	
	
		
	
		
			All checks were successful
		
		
	
	
		
			
				
	
				continuous-integration/drone/pr Build is passing
				
			
		
		
	
	
				
					
				
			
		
			All checks were successful
		
		
	
	continuous-integration/drone/pr Build is passing
				
			This commit is contained in:
		@@ -106,7 +106,7 @@ export class User extends Principal {
 | 
			
		||||
  * The user's profile picture.
 | 
			
		||||
  * We haven't decided yet if this will be a bas64 encoded image or just a link to the profile picture.
 | 
			
		||||
  */
 | 
			
		||||
  @Column({ nullable: true, unique: true })
 | 
			
		||||
  @Column({ nullable: true, unique: false })
 | 
			
		||||
  @IsString()
 | 
			
		||||
  @IsOptional()
 | 
			
		||||
  profilePic?: string;
 | 
			
		||||
@@ -115,7 +115,7 @@ export class User extends Principal {
 | 
			
		||||
  * The last time the user requested a password reset.
 | 
			
		||||
  * Used to prevent spamming of the password reset route.
 | 
			
		||||
  */
 | 
			
		||||
  @Column({ nullable: true, unique: true })
 | 
			
		||||
  @Column({ nullable: true, unique: false })
 | 
			
		||||
  @IsString()
 | 
			
		||||
  @IsOptional()
 | 
			
		||||
  resetRequestedTimestamp?: number;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										56
									
								
								src/tests/auth/auth_login.spec.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								src/tests/auth/auth_login.spec.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,56 @@
 | 
			
		||||
import axios from 'axios';
 | 
			
		||||
import { config } from '../../config';
 | 
			
		||||
const base = "http://localhost:" + config.internal_port
 | 
			
		||||
 | 
			
		||||
let axios_config;
 | 
			
		||||
 | 
			
		||||
beforeAll(async () => {
 | 
			
		||||
    axios_config = {
 | 
			
		||||
        validateStatus: undefined
 | 
			
		||||
    };
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
describe('POST /api/auth/login valid', () => {
 | 
			
		||||
    it('valid login should return 200', async () => {
 | 
			
		||||
        const res = await axios.post(base + '/api/auth/login', { username: "demo", password: "demo" }, axios_config);
 | 
			
		||||
        expect(res.status).toEqual(200);
 | 
			
		||||
        expect(res.headers['content-type']).toContain("application/json")
 | 
			
		||||
    });
 | 
			
		||||
});
 | 
			
		||||
// ---------------
 | 
			
		||||
describe('POST /api/auth/login invalid body', () => {
 | 
			
		||||
    it('Loging without a body should return 400', async () => {
 | 
			
		||||
        const res = await axios.post(base + '/api/auth/login', null, axios_config);
 | 
			
		||||
        expect(res.status).toEqual(400);
 | 
			
		||||
    });
 | 
			
		||||
    it('Loging without a password should return 400', async () => {
 | 
			
		||||
        const res = await axios.post(base + '/api/auth/login', { username: "demo" }, axios_config);
 | 
			
		||||
        expect(res.status).toEqual(400);
 | 
			
		||||
    });
 | 
			
		||||
    it('Loging with invalid mail format should return 400', async () => {
 | 
			
		||||
        const res = await axios.post(base + '/api/auth/login', { email: "demo", password: "demo" }, axios_config);
 | 
			
		||||
        expect(res.status).toEqual(400);
 | 
			
		||||
    });
 | 
			
		||||
    it('Loging without a username/mail should return 404', async () => {
 | 
			
		||||
        const res = await axios.post(base + '/api/auth/login', { password: "demo" }, axios_config);
 | 
			
		||||
        expect(res.status).toEqual(404);
 | 
			
		||||
    });
 | 
			
		||||
});
 | 
			
		||||
// ---------------
 | 
			
		||||
describe('POST /api/auth/login nonexistant user', () => {
 | 
			
		||||
    it('login with nonexistant username should return 404', async () => {
 | 
			
		||||
        const res = await axios.post(base + '/api/auth/login', { username: "-1", password: "demo" }, axios_config);
 | 
			
		||||
        expect(res.status).toEqual(404);
 | 
			
		||||
    });
 | 
			
		||||
    it('login with nonexistant mail should return 404', async () => {
 | 
			
		||||
        const res = await axios.post(base + '/api/auth/login', { email: "test@example.com", password: "demo" }, axios_config);
 | 
			
		||||
        expect(res.status).toEqual(404);
 | 
			
		||||
    });
 | 
			
		||||
});
 | 
			
		||||
// ---------------
 | 
			
		||||
describe('POST /api/auth/login wrong password', () => {
 | 
			
		||||
    it('login with wrong password should return 401', async () => {
 | 
			
		||||
        const res = await axios.post(base + '/api/auth/login', { username: "demo", password: "totallynotthecorrectpassword" }, axios_config);
 | 
			
		||||
        expect(res.status).toEqual(401);
 | 
			
		||||
    });
 | 
			
		||||
});
 | 
			
		||||
							
								
								
									
										58
									
								
								src/tests/auth/auth_logout.spec.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								src/tests/auth/auth_logout.spec.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,58 @@
 | 
			
		||||
import axios from 'axios';
 | 
			
		||||
import { config } from '../../config';
 | 
			
		||||
 | 
			
		||||
const base = "http://localhost:" + config.internal_port
 | 
			
		||||
 | 
			
		||||
const axios_config = {
 | 
			
		||||
    validateStatus: undefined
 | 
			
		||||
};;
 | 
			
		||||
 | 
			
		||||
beforeAll(async () => {
 | 
			
		||||
    const res_login = await axios.post(base + '/api/auth/login', { username: "demo", password: "demo" });
 | 
			
		||||
    await axios.post(base + '/api/users', {
 | 
			
		||||
        "firstname": "demo_logout",
 | 
			
		||||
        "middlename": "demo_logout",
 | 
			
		||||
        "lastname": "demo_logout",
 | 
			
		||||
        "username": "demo_logout",
 | 
			
		||||
        "password": "demo_logout"
 | 
			
		||||
    }, {
 | 
			
		||||
        headers: { "authorization": "Bearer " + res_login.data["access_token"] },
 | 
			
		||||
        validateStatus: undefined
 | 
			
		||||
    });
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
describe('POST /api/auth/logout valid', () => {
 | 
			
		||||
    let refresh_coookie;
 | 
			
		||||
    it('valid logout with token in cookie should return 200', async () => {
 | 
			
		||||
        const res_login = await axios.post(base + '/api/auth/login', { username: "demo_logout", password: "demo_logout" });
 | 
			
		||||
        refresh_coookie = res_login.headers["set-cookie"];
 | 
			
		||||
        const res = await axios.post(base + '/api/auth/logout', null, {
 | 
			
		||||
            headers: { "Cookie": refresh_coookie },
 | 
			
		||||
            validateStatus: undefined
 | 
			
		||||
        });
 | 
			
		||||
        expect(res.status).toEqual(200);
 | 
			
		||||
    });
 | 
			
		||||
    it('valid logout with token in body should return 200', async () => {
 | 
			
		||||
        const res_login = await axios.post(base + '/api/auth/login', { username: "demo_logout", password: "demo_logout" });
 | 
			
		||||
        const res = await axios.post(base + '/api/auth/logout', { token: res_login.data["refresh_token"] }, axios_config);
 | 
			
		||||
        expect(res.status).toEqual(200);
 | 
			
		||||
    });
 | 
			
		||||
    it('getting users after valid logout should return 401', async () => {
 | 
			
		||||
        const res = await axios.get(base + '/api/users', {
 | 
			
		||||
            headers: { "Cookie": refresh_coookie },
 | 
			
		||||
            validateStatus: undefined
 | 
			
		||||
        });
 | 
			
		||||
        expect(res.status).toEqual(401);
 | 
			
		||||
    });
 | 
			
		||||
});
 | 
			
		||||
// ---------------
 | 
			
		||||
describe('POST /api/auth/logout ivalid', () => {
 | 
			
		||||
    it('invalid logout without token should return 406', async () => {
 | 
			
		||||
        const res = await axios.post(base + '/api/auth/logout', null, axios_config);
 | 
			
		||||
        expect(res.status).toEqual(406);
 | 
			
		||||
    });
 | 
			
		||||
    it('invalid logout with invalid token in body should return 401', async () => {
 | 
			
		||||
        const res = await axios.post(base + '/api/auth/logout', { token: "1" }, axios_config);
 | 
			
		||||
        expect(res.status).toEqual(401);
 | 
			
		||||
    });
 | 
			
		||||
});
 | 
			
		||||
							
								
								
									
										49
									
								
								src/tests/auth/auth_refresh.spec.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								src/tests/auth/auth_refresh.spec.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,49 @@
 | 
			
		||||
import axios from 'axios';
 | 
			
		||||
import { config } from '../../config';
 | 
			
		||||
 | 
			
		||||
const base = "http://localhost:" + config.internal_port
 | 
			
		||||
 | 
			
		||||
const axios_config = {
 | 
			
		||||
    validateStatus: undefined
 | 
			
		||||
};;
 | 
			
		||||
 | 
			
		||||
beforeAll(async () => {
 | 
			
		||||
    const res_login = await axios.post(base + '/api/auth/login', { username: "demo", password: "demo" });
 | 
			
		||||
    await axios.post(base + '/api/users', {
 | 
			
		||||
        "firstname": "demo_refresh",
 | 
			
		||||
        "middlename": "demo_refresh",
 | 
			
		||||
        "lastname": "demo_refresh",
 | 
			
		||||
        "username": "demo_refresh",
 | 
			
		||||
        "password": "demo_refresh"
 | 
			
		||||
    }, {
 | 
			
		||||
        headers: { "authorization": "Bearer " + res_login.data["access_token"] },
 | 
			
		||||
        validateStatus: undefined
 | 
			
		||||
    });
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
describe('POST /api/auth/refresh valid', () => {
 | 
			
		||||
    it('valid refresh with token in cookie should return 200', async () => {
 | 
			
		||||
        const res_login = await axios.post(base + '/api/auth/login', { username: "demo_refresh", password: "demo_refresh" });
 | 
			
		||||
        const res = await axios.post(base + '/api/auth/refresh', null, {
 | 
			
		||||
            headers: { "Cookie": res_login.headers["set-cookie"] },
 | 
			
		||||
            validateStatus: undefined
 | 
			
		||||
        });
 | 
			
		||||
        expect(res.status).toEqual(200);
 | 
			
		||||
    });
 | 
			
		||||
    it('valid refresh with token in body should return 200', async () => {
 | 
			
		||||
        const res_login = await axios.post(base + '/api/auth/login', { username: "demo_refresh", password: "demo_refresh" });
 | 
			
		||||
        const res = await axios.post(base + '/api/auth/refresh', { token: res_login.data["refresh_token"] }, axios_config);
 | 
			
		||||
        expect(res.status).toEqual(200);
 | 
			
		||||
    });
 | 
			
		||||
});
 | 
			
		||||
// ---------------
 | 
			
		||||
describe('POST /api/auth/refresh ivalid', () => {
 | 
			
		||||
    it('invalid refresh without token should return 406', async () => {
 | 
			
		||||
        const res = await axios.post(base + '/api/auth/refresh', null, axios_config);
 | 
			
		||||
        expect(res.status).toEqual(406);
 | 
			
		||||
    });
 | 
			
		||||
    it('invalid refresh with invalid token in body should return 401', async () => {
 | 
			
		||||
        const res = await axios.post(base + '/api/auth/refresh', { token: "1" }, axios_config);
 | 
			
		||||
        expect(res.status).toEqual(401);
 | 
			
		||||
    });
 | 
			
		||||
});
 | 
			
		||||
							
								
								
									
										75
									
								
								src/tests/auth/auth_reset.spec.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								src/tests/auth/auth_reset.spec.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,75 @@
 | 
			
		||||
import axios from 'axios';
 | 
			
		||||
import { config } from '../../config';
 | 
			
		||||
 | 
			
		||||
const base = "http://localhost:" + config.internal_port
 | 
			
		||||
 | 
			
		||||
const axios_config = {
 | 
			
		||||
    validateStatus: undefined
 | 
			
		||||
};;
 | 
			
		||||
 | 
			
		||||
beforeAll(async () => {
 | 
			
		||||
    const res_login = await axios.post(base + '/api/auth/login', { username: "demo", password: "demo" });
 | 
			
		||||
    await axios.post(base + '/api/users', {
 | 
			
		||||
        "firstname": "demo_reset",
 | 
			
		||||
        "middlename": "demo_reset",
 | 
			
		||||
        "lastname": "demo_reset",
 | 
			
		||||
        "username": "demo_reset",
 | 
			
		||||
        "password": "demo_reset"
 | 
			
		||||
    }, {
 | 
			
		||||
        headers: { "authorization": "Bearer " + res_login.data["access_token"] },
 | 
			
		||||
        validateStatus: undefined
 | 
			
		||||
    });
 | 
			
		||||
    await axios.post(base + '/api/users', {
 | 
			
		||||
        "firstname": "demo_reset2",
 | 
			
		||||
        "middlename": "demo_reset2",
 | 
			
		||||
        "lastname": "demo_reset2",
 | 
			
		||||
        "username": "demo_reset2",
 | 
			
		||||
        "password": "demo_reset2"
 | 
			
		||||
    }, {
 | 
			
		||||
        headers: { "authorization": "Bearer " + res_login.data["access_token"] },
 | 
			
		||||
        validateStatus: undefined
 | 
			
		||||
    });
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
describe('POST /api/auth/reset valid', () => {
 | 
			
		||||
    let reset_token;
 | 
			
		||||
    it('valid reset token request should return 200', async () => {
 | 
			
		||||
        const res1 = await axios.post(base + '/api/auth/reset', { username: "demo_reset" });
 | 
			
		||||
        reset_token = res1.data.resetToken;
 | 
			
		||||
        expect(res1.status).toEqual(200);
 | 
			
		||||
    });
 | 
			
		||||
    it('valid password reset should return 200', async () => {
 | 
			
		||||
        const res2 = await axios.post(base + '/api/auth/reset/' + reset_token, { password: "demo" }, axios_config);
 | 
			
		||||
        expect(res2.status).toEqual(200);
 | 
			
		||||
    });
 | 
			
		||||
    it('valid login after reset should return 200', async () => {
 | 
			
		||||
        const res = await axios.post(base + '/api/auth/login', { username: "demo_reset", password: "demo" });
 | 
			
		||||
        expect(res.status).toEqual(200);
 | 
			
		||||
    });
 | 
			
		||||
});
 | 
			
		||||
// ---------------
 | 
			
		||||
describe('POST /api/auth/reset invalid requests', () => {
 | 
			
		||||
    it('request another password reset before the timeout should return 406', async () => {
 | 
			
		||||
        const res1 = await axios.post(base + '/api/auth/reset', { username: "demo_reset2" }, axios_config);
 | 
			
		||||
        const res2 = await axios.post(base + '/api/auth/reset', { username: "demo_reset2" }, axios_config);
 | 
			
		||||
        expect(res2.status).toEqual(406);
 | 
			
		||||
    });
 | 
			
		||||
});
 | 
			
		||||
// ---------------
 | 
			
		||||
describe('POST /api/auth/reset invalid token', () => {
 | 
			
		||||
    it('providing a invalid reset token should return 401', async () => {
 | 
			
		||||
        const res2 = await axios.post(base + '/api/auth/reset/' + "123123", { password: "demo" }, axios_config);
 | 
			
		||||
        expect(res2.status).toEqual(401);
 | 
			
		||||
    });
 | 
			
		||||
    it('providing no reset token should return 404', async () => {
 | 
			
		||||
        const res2 = await axios.post(base + '/api/auth/reset/' + "", { password: "demo" }, axios_config);
 | 
			
		||||
        expect(res2.status).toEqual(404);
 | 
			
		||||
    });
 | 
			
		||||
});
 | 
			
		||||
// ---------------
 | 
			
		||||
describe('POST /api/auth/reset invalid body', () => {
 | 
			
		||||
    it('providing no password should return 400', async () => {
 | 
			
		||||
        const res2 = await axios.post(base + '/api/auth/reset/' + "123123", null, axios_config);
 | 
			
		||||
        expect(res2.status).toEqual(400);
 | 
			
		||||
    });
 | 
			
		||||
});
 | 
			
		||||
		Reference in New Issue
	
	Block a user