refactor: switch to HttpOnly cookie (#660)

* Switch to httpOnly cookie
* create endpoint to retrieve temporary collaboration token

* cleanups
This commit is contained in:
Philip Okugbe
2025-01-22 22:11:11 +00:00
committed by GitHub
parent f2235fd2a2
commit 990612793f
29 changed files with 240 additions and 276 deletions
@@ -7,7 +7,6 @@ import {
import { LoginDto } from '../dto/login.dto';
import { CreateUserDto } from '../dto/create-user.dto';
import { TokenService } from './token.service';
import { TokensDto } from '../dto/tokens.dto';
import { SignupService } from './signup.service';
import { CreateAdminUserDto } from '../dto/create-admin-user.dto';
import { UserRepo } from '@docmost/db/repos/user/user.repo';
@@ -60,24 +59,17 @@ export class AuthService {
user.lastLoginAt = new Date();
await this.userRepo.updateLastLogin(user.id, workspaceId);
const tokens: TokensDto = await this.tokenService.generateTokens(user);
return { tokens };
return this.tokenService.generateAccessToken(user);
}
async register(createUserDto: CreateUserDto, workspaceId: string) {
const user = await this.signupService.signup(createUserDto, workspaceId);
const tokens: TokensDto = await this.tokenService.generateTokens(user);
return { tokens };
return this.tokenService.generateAccessToken(user);
}
async setup(createAdminUserDto: CreateAdminUserDto) {
const user = await this.signupService.initialSetup(createAdminUserDto);
const tokens: TokensDto = await this.tokenService.generateTokens(user);
return { tokens };
return this.tokenService.generateAccessToken(user);
}
async changePassword(
@@ -186,7 +178,7 @@ export class AuthService {
trx,
);
trx
await trx
.deleteFrom('userTokens')
.where('userId', '=', user.id)
.where('type', '=', UserTokenType.FORGOT_PASSWORD)
@@ -200,9 +192,7 @@ export class AuthService {
template: emailTemplate,
});
const tokens: TokensDto = await this.tokenService.generateTokens(user);
return { tokens };
return this.tokenService.generateAccessToken(user);
}
async verifyUserToken(
@@ -222,4 +212,12 @@ export class AuthService {
throw new BadRequestException('Invalid or expired token');
}
}
async getCollabToken(userId: string, workspaceId: string) {
const token = await this.tokenService.generateCollabToken(
userId,
workspaceId,
);
return { token };
}
}
@@ -1,8 +1,7 @@
import { Injectable } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import { EnvironmentService } from '../../../integrations/environment/environment.service';
import { TokensDto } from '../dto/tokens.dto';
import { JwtPayload, JwtRefreshPayload, JwtType } from '../dto/jwt-payload';
import { JwtCollabPayload, JwtPayload, JwtType } from '../dto/jwt-payload';
import { User } from '@docmost/db/types/entity.types';
@Injectable()
@@ -22,26 +21,19 @@ export class TokenService {
return this.jwtService.sign(payload);
}
async generateRefreshToken(
async generateCollabToken(
userId: string,
workspaceId: string,
): Promise<string> {
const payload: JwtRefreshPayload = {
const payload: JwtCollabPayload = {
sub: userId,
workspaceId,
type: JwtType.REFRESH,
type: JwtType.COLLAB,
};
const expiresIn = this.environmentService.getJwtTokenExpiresIn();
const expiresIn = '24h';
return this.jwtService.sign(payload, { expiresIn });
}
async generateTokens(user: User): Promise<TokensDto> {
return {
accessToken: await this.generateAccessToken(user),
refreshToken: await this.generateRefreshToken(user.id, user.workspaceId),
};
}
async verifyJwt(token: string) {
return this.jwtService.verifyAsync(token, {
secret: this.environmentService.getAppSecret(),