Skip to content

Commit f7b3eb5

Browse files
author
hersveit
committed
sign-out
1 parent 52255ea commit f7b3eb5

File tree

3 files changed

+46
-13
lines changed

3 files changed

+46
-13
lines changed

src/services/auth/__tests__/auth.service.spec.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,4 +372,29 @@ describe('AuthService', () => {
372372
expect(confirmResult).toBeInstanceOf(CannotFindEmailConfirm);
373373
});
374374
});
375+
376+
describe('signOut', () => {
377+
it('should delete refresh token from database on signOut', async () => {
378+
userService.findUser.mockResolvedValueOnce(user);
379+
380+
await authService.signOut(user.email);
381+
382+
expect(userService.findUser).toBeCalledTimes(1);
383+
expect(userService.findUser).toBeCalledWith({ email: user.email });
384+
expect(refreshTokensRepository.Dao.delete).toBeCalledTimes(1);
385+
expect(refreshTokensRepository.Dao.delete).toBeCalledWith({
386+
where: { userId: user.id },
387+
});
388+
});
389+
390+
it('should not call delete on error when findUser function is called', async () => {
391+
userService.findUser.mockResolvedValueOnce(new CannotFindUser());
392+
393+
await authService.signOut(user.email);
394+
395+
expect(userService.findUser).toBeCalledTimes(1);
396+
expect(userService.findUser).toBeCalledWith({ email: user.email });
397+
expect(refreshTokensRepository.Dao.delete).toBeCalledTimes(0);
398+
});
399+
});
375400
});

src/services/auth/auth.service.ts

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,10 @@ import {
2222
UserPayload,
2323
} from './auth.model';
2424
import { JwtStrategy } from './strategies/jwt.strategy';
25-
import { CannotFindEmailConfirm } from '../../repositories/repositoryErrors.model';
25+
import { CannotFindEmailConfirm, CannotFindUser } from '../../repositories/repositoryErrors.model';
2626
import { User } from '@prisma/client';
2727
import { DatabaseService } from '../database/database.service';
28+
import { EmailOrPasswordIncorrect, UserAlreadyExist } from '../user/user.model';
2829

2930
@Injectable()
3031
export class AuthServiceProvider {
@@ -40,7 +41,7 @@ export class AuthServiceProvider {
4041
async signUp(payload: UserPayload) {
4142
const user = await this.userService.createUser(payload);
4243
if (isError(user)) {
43-
return user;
44+
return user as UserAlreadyExist;
4445
}
4546

4647
const sendEmailResult = await this.sendConfirmEmail({ id: user.id });
@@ -54,7 +55,7 @@ export class AuthServiceProvider {
5455
async signIn(payload: UserPayload) {
5556
const userResult = await this.userService.findVerifiedUser(payload);
5657
if (isError(userResult)) {
57-
return userResult;
58+
return userResult as EmailOrPasswordIncorrect;
5859
}
5960

6061
if (!userResult.emailConfirmed) {
@@ -64,6 +65,13 @@ export class AuthServiceProvider {
6465
return this.generateTokensWithCookie(userResult.id, userResult.email);
6566
}
6667

68+
async signOut(email: string) {
69+
const user = await this.userService.findUser({ email });
70+
if (!isError(user)) {
71+
await this.refreshTokens.Dao.delete({ where: { userId: user.id } });
72+
}
73+
}
74+
6775
async confirmEmail(confirmUuid: string) {
6876
const confirmEntityResult = await this.emailConfirms.Dao.findFirst({
6977
where: { confirmUuid },
@@ -74,7 +82,7 @@ export class AuthServiceProvider {
7482

7583
const userResult = await this.userService.findUser({ id: confirmEntityResult.userId });
7684
if (isError(userResult)) {
77-
return userResult;
85+
return userResult as CannotFindUser;
7886
}
7987

8088
if (userResult.emailConfirmed) {
@@ -83,7 +91,7 @@ export class AuthServiceProvider {
8391

8492
const confirmedResult = await this.userService.confirmEmail({ id: userResult.id });
8593
if (isError(confirmedResult)) {
86-
return confirmedResult;
94+
return confirmedResult as CannotFindUser;
8795
}
8896

8997
return this.generateTokensWithCookie(userResult.id, userResult.email);
@@ -92,7 +100,7 @@ export class AuthServiceProvider {
92100
async sendConfirmEmail(where: Pick<User, 'id'>) {
93101
const userResult = await this.userService.findUser(where);
94102
if (isError(userResult)) {
95-
return userResult;
103+
return userResult as CannotFindUser;
96104
}
97105

98106
if (userResult.emailConfirmed) {
@@ -115,7 +123,7 @@ export class AuthServiceProvider {
115123

116124
async generateTokens(id: number, email: string) {
117125
const refreshToken = this.jwtService.sign(
118-
{ email },
126+
{ email, date: Date.now() },
119127
{
120128
expiresIn: this.configService.JWT_REFRESH_TOKEN_EXPIRATION_TIME,
121129
secret: this.configService.JWT_REFRESH_TOKEN_SECRET,
@@ -126,7 +134,7 @@ export class AuthServiceProvider {
126134

127135
const user = await this.userService.findUser({ id });
128136
if (isError(user)) {
129-
return user;
137+
return user as CannotFindUser;
130138
}
131139

132140
if (user.refreshToken) {
@@ -146,7 +154,7 @@ export class AuthServiceProvider {
146154
}
147155

148156
return {
149-
accessToken: this.jwtService.sign({ email }),
157+
accessToken: this.jwtService.sign({ email, date: Date.now() }),
150158
refreshToken,
151159
};
152160
}
@@ -155,13 +163,14 @@ export class AuthServiceProvider {
155163
const tokens = await this.generateTokens(id, email);
156164

157165
if (isError(tokens)) {
158-
return tokens;
166+
return tokens as CannotFindUser;
159167
}
160168

161169
return {
162170
accessToken: tokens.accessToken,
163-
// eslint-disable-next-line max-len
164-
refreshCookie: `Refresh=${tokens.refreshToken}; HttpOnly; Path=/; Max-Age=${this.configService.JWT_REFRESH_TOKEN_EXPIRATION_TIME}`,
171+
refreshCookie:
172+
`Refresh=${tokens.refreshToken}; HttpOnly; ` +
173+
`Path=/; Max-Age=${this.configService.JWT_REFRESH_TOKEN_EXPIRATION_TIME}`,
165174
};
166175
}
167176
}

src/services/auth/strategies/jwt-refresh.strategy.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ export class JwtRefreshTokenStrategy extends PassportStrategy(Strategy, 'jwt-ref
3131
});
3232

3333
const refreshToken = user?.refreshToken?.hash;
34-
3534
const token: string | undefined = request.cookies?.Refresh;
3635

3736
if (user && refreshToken && token && sha256(token) === refreshToken) {

0 commit comments

Comments
 (0)