- 자동 로그인 로직 cookie 로 변경
This commit is contained in:
28
certs/localhost+2-key.pem
Normal file
28
certs/localhost+2-key.pem
Normal file
@@ -0,0 +1,28 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC1GqPn9O+FRM+a
|
||||
hQvEAjgjI7HXdRdeRJsX3K2BqNGYBR8Lat4fMskY4Es7WYNCDl9d/fFQd+K/gpjj
|
||||
sRnX0Bf3CYjVNlhTqdwoOFBPGUQ4i8fuSRM4rDvAq4enb+7RVWjE53MGgqQ0RdRQ
|
||||
Hyx95pEWTz0FzpNlzOzEGEdv8zBwbwgZBU73F4aCDNY0FLaaKepr1/NqdUA8xZYo
|
||||
sAbJvIkWJ/QS2F2/WwQZYQ3TLWtg4/2uDpGWbpQUwRnWZ7ma+Gcz/hJwQhoml4q4
|
||||
bHXrIAsCz/NFNYs7K5wCmIdTjLw2PcETJSEQMbGSk7CMIuiUd0ShVDfpBROIAlmF
|
||||
XAheZ/lNAgMBAAECggEAT1H7t/xva89XnjXnkVHnhHx9yABg28jwpOLim4d1RT/4
|
||||
+Oc1ojR8H4kdakEqXCQvYNt4deYMShTJIfDPgNaDqI9kfv3ucbZT1snTYtGOL7YJ
|
||||
OzSGVqwY/6ohIBTGZKkj2hoFJzTQ9pQfCXid5Aa4RS0vbPutU0kN6lU39LBu5s79
|
||||
8MGGu70Qcd63BRpyOxKbbWCbZ0S/7JRShng0GA8ILBvMCZdzZ7RZktpa+bA7Q6i7
|
||||
PM5zxxmxygmFQXOAizTB2KoeLEu/qb44kypK6aw9nMKEZebqzuF5bOFMlCR67Cfx
|
||||
QblFW0JQckef7DCc4ThPEnAXwEPSlsv2P//dbX1TgQKBgQDctIA/GZmzSXVtsUws
|
||||
aPPeAvKMWGFSGsq/9rcy2G7KBTHBQW5/763T6N7HKVpZwRaabiSxgrZekd6d9oTP
|
||||
XWpmnFQZgtLRtXLPXilCK8Udoi6HejGuXWvviFdfPUqhPh3tw6uCaFO7qT4pUiwO
|
||||
hTq4W5Cm+xy/q12m7cEDfoPeMwKBgQDSEOdQY5f5C6YrZvG2zrTZUvS8VW4NFhkY
|
||||
vSZBGqiACYGKq/7erMoAdtLrcYBnEMiLufn+tSInflw2I+ALEo4r2lcBAQncXuWj
|
||||
gnpM+DpTwRfZmGYs3jXA5eVRRzG0FBFLFyiBE62f0tvJjALB7V7vfpCswJGvPIyb
|
||||
p2P16jZKfwKBgQCn4VkoJlYGzZrYTKPvqAnQV5ed7+BfbufIq2dg8scbPmZBZX8j
|
||||
K/KinaFQB4Glgj2qTJv2tsH4H6chqxINFjbIRKOoIB4yzH2/hRWHMvomd2ZDQUyn
|
||||
IILo2mHznRC2pCRp5owAj1EaDzusfMfsZ6Vp9KSMj7inhzeesX0/Ji4yhwKBgHgh
|
||||
sJc5jYSgU9RIV/0qcyRBm7JEzN3xAEM0kLb0rt4iEZIjUGs5t3/SdEavLzZB096M
|
||||
adpu7exWCBfyJkNOxj1v7Qem92OuZXc/u/9eicSyDZij3fLU1TrOfnkf1N3eCBHA
|
||||
WaqPfWCELqsxRbZvsDYYVFZm/imP3/14GeNdoNSzAoGALFD3YdZ5bIETcD8hwXd7
|
||||
P9HXPQZag919fFe0dhPDauC5dgvgfLF2d88q0MPCqMK6ngTMVzrMh4X/u0XH1N3v
|
||||
LiQEBp4P0EX1z5DEj8eLajV0JgOyt1zzymZ3Jk7DDyfcYl+bVetB2R9Gd3MuV98t
|
||||
Sz72wO/jh1/w+SN07F9VS0w=
|
||||
-----END PRIVATE KEY-----
|
||||
26
certs/localhost+2.pem
Normal file
26
certs/localhost+2.pem
Normal file
@@ -0,0 +1,26 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIETjCCAragAwIBAgIQJ0x1ttig1msjzZOJWJwnITANBgkqhkiG9w0BAQsFADB7
|
||||
MR4wHAYDVQQKExVta2NlcnQgZGV2ZWxvcG1lbnQgQ0ExKDAmBgNVBAsMH+uwse2W
|
||||
peuLqFxiYWVreWFuZ2RhbkDrsLHtlqXri6gxLzAtBgNVBAMMJm1rY2VydCDrsLHt
|
||||
lqXri6hcYmFla3lhbmdkYW5A67Cx7Zal64uoMB4XDTI1MTIwNzEwMDIyNVoXDTI4
|
||||
MDMwNzEwMDIyNVowUzEnMCUGA1UEChMebWtjZXJ0IGRldmVsb3BtZW50IGNlcnRp
|
||||
ZmljYXRlMSgwJgYDVQQLDB/rsLHtlqXri6hcYmFla3lhbmdkYW5A67Cx7Zal64uo
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtRqj5/TvhUTPmoULxAI4
|
||||
IyOx13UXXkSbF9ytgajRmAUfC2reHzLJGOBLO1mDQg5fXf3xUHfiv4KY47EZ19AX
|
||||
9wmI1TZYU6ncKDhQTxlEOIvH7kkTOKw7wKuHp2/u0VVoxOdzBoKkNEXUUB8sfeaR
|
||||
Fk89Bc6TZczsxBhHb/MwcG8IGQVO9xeGggzWNBS2minqa9fzanVAPMWWKLAGybyJ
|
||||
Fif0Ethdv1sEGWEN0y1rYOP9rg6Rlm6UFMEZ1me5mvhnM/4ScEIaJpeKuGx16yAL
|
||||
As/zRTWLOyucApiHU4y8Nj3BEyUhEDGxkpOwjCLolHdEoVQ36QUTiAJZhVwIXmf5
|
||||
TQIDAQABo3YwdDAOBgNVHQ8BAf8EBAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUHAwEw
|
||||
HwYDVR0jBBgwFoAU9/lqZ9lo2f1oLg+JnBYubfpE4OEwLAYDVR0RBCUwI4IJbG9j
|
||||
YWxob3N0hwR/AAABhxAAAAAAAAAAAAAAAAAAAAABMA0GCSqGSIb3DQEBCwUAA4IB
|
||||
gQBNsZYSSGE6m3ve8bPGISSdlSU/pi1GVqOC4xxVD8JUeGNZeYAv8AJQ6w/496wK
|
||||
KTFL6PDOavHW37mWBEgz+fZe2AjOZK/hz/eOcKHTFhVRZo1snt5VuLk4PtAGmgn8
|
||||
xyyQUz/2wwlTqb0AgLrt1hLTnbSIWvBnFl3VdCnH0E2xsIPZUMFzcjVHTERJWvAS
|
||||
IanurnpeO/W3uNduu7UmGk03GDzTG8dXwVsSSE/HoXxscXSIP9qMvKOPeQvucd+X
|
||||
XkaYUkbjDhwoKqDB0rDmvbPkFcsAGuq8qpbPPavhoXgtdqO30lZfbTPWPq1qz99S
|
||||
nW9ihMfmwarw5s/LCXiQO70nMbcZMZ6UAqEhX4UUfGD0j5jHe3fPOyT4v0lLfmxp
|
||||
P4eoSiWoIfp/f9ZBn9zca5km9iGNT+n1Jrt6fOTIycPVu2gE7S4qXcHhVHWondle
|
||||
bMFLGbjZ75Qwc9HdnoY7Do8Vj+CPvSfhAAPehPf8D1GVlazmiuHql4fny1qbGw//
|
||||
YEQ=
|
||||
-----END CERTIFICATE-----
|
||||
@@ -9,5 +9,13 @@ export default defineConfig({
|
||||
out: "./drizzle",
|
||||
dbCredentials: {
|
||||
url: process.env.PG_DATABASE_URL!
|
||||
}
|
||||
},
|
||||
tablesFilter: [
|
||||
'account',
|
||||
'schedule',
|
||||
'comment',
|
||||
'follow',
|
||||
'favorite',
|
||||
'participant'
|
||||
]
|
||||
});
|
||||
|
||||
@@ -18,8 +18,8 @@ export const commentRelations = relations(comment, ({one, many}) => ({
|
||||
|
||||
export const accountRelations = relations(account, ({many}) => ({
|
||||
comments: many(comment),
|
||||
schedules: many(schedule),
|
||||
participants: many(participant),
|
||||
schedules: many(schedule),
|
||||
favorites: many(favorite),
|
||||
follows_follower: many(follow, {
|
||||
relationName: "follow_follower_account_id"
|
||||
@@ -29,15 +29,6 @@ export const accountRelations = relations(account, ({many}) => ({
|
||||
}),
|
||||
}));
|
||||
|
||||
export const scheduleRelations = relations(schedule, ({one, many}) => ({
|
||||
account: one(account, {
|
||||
fields: [schedule.owner],
|
||||
references: [account.id]
|
||||
}),
|
||||
participants: many(participant),
|
||||
favorites: many(favorite),
|
||||
}));
|
||||
|
||||
export const participantRelations = relations(participant, ({one}) => ({
|
||||
schedule: one(schedule, {
|
||||
fields: [participant.scheduleId],
|
||||
@@ -49,6 +40,15 @@ export const participantRelations = relations(participant, ({one}) => ({
|
||||
}),
|
||||
}));
|
||||
|
||||
export const scheduleRelations = relations(schedule, ({one, many}) => ({
|
||||
participants: many(participant),
|
||||
account: one(account, {
|
||||
fields: [schedule.owner],
|
||||
references: [account.id]
|
||||
}),
|
||||
favorites: many(favorite),
|
||||
}));
|
||||
|
||||
export const favoriteRelations = relations(favorite, ({one}) => ({
|
||||
schedule: one(schedule, {
|
||||
fields: [favorite.scheduleId],
|
||||
|
||||
@@ -1,7 +1,23 @@
|
||||
import { pgTable, foreignKey, uuid, text, date, boolean, index, varchar, primaryKey } from "drizzle-orm/pg-core"
|
||||
import { pgTable, foreignKey, uuid, text, date, boolean, varchar, index, time, primaryKey, pgSequence } from "drizzle-orm/pg-core"
|
||||
import { sql } from "drizzle-orm"
|
||||
|
||||
|
||||
export const versionIdSeq = pgSequence("version_id_seq", { startWith: "1", increment: "1", minValue: "1", maxValue: "9223372036854775807", cache: "1", cycle: false })
|
||||
export const accessTokenIdSeq = pgSequence("access_token_id_seq", { startWith: "1", increment: "1", minValue: "1", maxValue: "9223372036854775807", cache: "1", cycle: false })
|
||||
export const oauth2ApplicationIdSeq = pgSequence("oauth2_application_id_seq", { startWith: "1", increment: "1", minValue: "1", maxValue: "9223372036854775807", cache: "1", cycle: false })
|
||||
export const oauth2AuthorizationCodeIdSeq = pgSequence("oauth2_authorization_code_id_seq", { startWith: "1", increment: "1", minValue: "1", maxValue: "9223372036854775807", cache: "1", cycle: false })
|
||||
export const oauth2GrantIdSeq = pgSequence("oauth2_grant_id_seq", { startWith: "1", increment: "1", minValue: "1", maxValue: "9223372036854775807", cache: "1", cycle: false })
|
||||
export const loginSourceIdSeq = pgSequence("login_source_id_seq", { startWith: "1", increment: "1", minValue: "1", maxValue: "9223372036854775807", cache: "1", cycle: false })
|
||||
export const twoFactorIdSeq = pgSequence("two_factor_id_seq", { startWith: "1", increment: "1", minValue: "1", maxValue: "9223372036854775807", cache: "1", cycle: false })
|
||||
export const webauthnCredentialIdSeq = pgSequence("webauthn_credential_id_seq", { startWith: "1", increment: "1", minValue: "1", maxValue: "9223372036854775807", cache: "1", cycle: false })
|
||||
export const dbfsMetaIdSeq = pgSequence("dbfs_meta_id_seq", { startWith: "1", increment: "1", minValue: "1", maxValue: "9223372036854775807", cache: "1", cycle: false })
|
||||
export const dbfsDataIdSeq = pgSequence("dbfs_data_id_seq", { startWith: "1", increment: "1", minValue: "1", maxValue: "9223372036854775807", cache: "1", cycle: false })
|
||||
export const noticeIdSeq = pgSequence("notice_id_seq", { startWith: "1", increment: "1", minValue: "1", maxValue: "9223372036854775807", cache: "1", cycle: false })
|
||||
export const systemSettingIdSeq = pgSequence("system_setting_id_seq", { startWith: "1", increment: "1", minValue: "1", maxValue: "9223372036854775807", cache: "1", cycle: false })
|
||||
export const badgeIdSeq = pgSequence("badge_id_seq", { startWith: "1", increment: "1", minValue: "1", maxValue: "9223372036854775807", cache: "1", cycle: false })
|
||||
export const userBadgeIdSeq = pgSequence("user_badge_id_seq", { startWith: "1", increment: "1", minValue: "1", maxValue: "9223372036854775807", cache: "1", cycle: false })
|
||||
export const userBlockingIdSeq = pgSequence("user_blocking_id_seq", { startWith: "1", increment: "1", minValue: "1", maxValue: "9223372036854775807", cache: "1", cycle: false })
|
||||
export const emailAddressIdSeq = pgSequence("email_address_id_seq", { startWith: "1", increment: "1", minValue: "1", maxValue: "9223372036854775807", cache: "1", cycle: false })
|
||||
|
||||
export const comment = pgTable("comment", {
|
||||
id: uuid().primaryKey().notNull(),
|
||||
@@ -23,30 +39,6 @@ export const comment = pgTable("comment", {
|
||||
}),
|
||||
]);
|
||||
|
||||
export const schedule = pgTable("schedule", {
|
||||
id: uuid().primaryKey().notNull(),
|
||||
name: varchar(),
|
||||
startAt: date("start_at"),
|
||||
endAt: date("end_at"),
|
||||
status: varchar(),
|
||||
content: text(),
|
||||
isDeleted: boolean("is_deleted").default(false),
|
||||
type: varchar(),
|
||||
createdAt: date("created_at"),
|
||||
owner: uuid(),
|
||||
}, (table) => [
|
||||
index("schedule_enddatetime_idx").using("btree", table.endAt.asc().nullsLast().op("date_ops")),
|
||||
index("schedule_name_idx").using("btree", table.name.asc().nullsLast().op("text_ops"), table.content.asc().nullsLast().op("text_ops")),
|
||||
index("schedule_startdatetime_idx").using("btree", table.startAt.asc().nullsLast().op("date_ops")),
|
||||
index("schedule_status_idx").using("btree", table.status.asc().nullsLast().op("text_ops")),
|
||||
index("schedule_type_idx").using("btree", table.type.asc().nullsLast().op("text_ops")),
|
||||
foreignKey({
|
||||
columns: [table.owner],
|
||||
foreignColumns: [account.id],
|
||||
name: "schedule_user_fk"
|
||||
}),
|
||||
]);
|
||||
|
||||
export const account = pgTable("account", {
|
||||
name: varchar().notNull(),
|
||||
email: varchar().notNull(),
|
||||
@@ -79,6 +71,33 @@ export const participant = pgTable("participant", {
|
||||
}),
|
||||
]);
|
||||
|
||||
export const schedule = pgTable("schedule", {
|
||||
id: uuid().primaryKey().notNull(),
|
||||
name: varchar(),
|
||||
startDate: date("start_date"),
|
||||
endDate: date("end_date"),
|
||||
status: varchar(),
|
||||
content: text(),
|
||||
isDeleted: boolean("is_deleted").default(false),
|
||||
type: varchar(),
|
||||
createdAt: date("created_at"),
|
||||
owner: uuid(),
|
||||
style: varchar(),
|
||||
startTime: time("start_time"),
|
||||
endTime: time("end_time"),
|
||||
}, (table) => [
|
||||
index("schedule_enddatetime_idx").using("btree", table.endDate.asc().nullsLast().op("date_ops")),
|
||||
index("schedule_name_idx").using("btree", table.name.asc().nullsLast().op("text_ops"), table.content.asc().nullsLast().op("text_ops")),
|
||||
index("schedule_startdatetime_idx").using("btree", table.startDate.asc().nullsLast().op("date_ops")),
|
||||
index("schedule_status_idx").using("btree", table.status.asc().nullsLast().op("text_ops")),
|
||||
index("schedule_type_idx").using("btree", table.type.asc().nullsLast().op("text_ops")),
|
||||
foreignKey({
|
||||
columns: [table.owner],
|
||||
foreignColumns: [account.id],
|
||||
name: "schedule_user_fk"
|
||||
}),
|
||||
]);
|
||||
|
||||
export const favorite = pgTable("favorite", {
|
||||
isDeleted: boolean("is_deleted").default(false),
|
||||
createdAt: date("created_at"),
|
||||
|
||||
@@ -20,9 +20,13 @@
|
||||
"test:watch": "jest --watch",
|
||||
"test:cov": "jest --coverage",
|
||||
"test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
|
||||
"test:e2e": "jest --config ./test/jest-e2e.json"
|
||||
"test:e2e": "jest --config ./test/jest-e2e.json",
|
||||
"drizzle-pull:local": "dotenv -e .env.local -- drizzle-kit pull",
|
||||
"drizzle-pull:dev": "dotenv -e .env.dev -- drizzle-kit pull",
|
||||
"drizzle-pull:prod": "dotenv -e .env.prod -- drizzle-kit pull"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fastify/cookie": "^11.0.2",
|
||||
"@nestjs/class-transformer": "^0.4.0",
|
||||
"@nestjs/class-validator": "^0.13.4",
|
||||
"@nestjs/common": "^11.0.1",
|
||||
@@ -64,6 +68,7 @@
|
||||
"@types/pg": "^8.15.6",
|
||||
"@types/supertest": "^6.0.2",
|
||||
"cross-env": "^10.1.0",
|
||||
"dotenv-cli": "^11.0.0",
|
||||
"eslint": "^9.18.0",
|
||||
"eslint-config-prettier": "^10.0.1",
|
||||
"eslint-plugin-prettier": "^5.2.2",
|
||||
|
||||
17
src/main.ts
17
src/main.ts
@@ -5,11 +5,23 @@ import {
|
||||
NestFastifyApplication
|
||||
} from '@nestjs/platform-fastify';
|
||||
import { AllExceptionsFilter } from './common/filters/all-exceptions.filter';
|
||||
import fastifyCookie from '@fastify/cookie';
|
||||
import * as path from 'path';
|
||||
import * as fs from 'fs';
|
||||
|
||||
async function bootstrap() {
|
||||
const isProd = process.env.NODE_ENV === 'prod';
|
||||
let httpsOptions = {};
|
||||
if (!isProd) {
|
||||
const certPath = path.join(__dirname, "..\\..", "certs");
|
||||
httpsOptions = {
|
||||
key: fs.readFileSync(path.join(certPath, 'localhost+2-key.pem')),
|
||||
cert: fs.readFileSync(path.join(certPath, 'localhost+2.pem'))
|
||||
};
|
||||
}
|
||||
const app = await NestFactory.create<NestFastifyApplication>(
|
||||
AppModule,
|
||||
new FastifyAdapter()
|
||||
new FastifyAdapter({ https: httpsOptions })
|
||||
);
|
||||
app.enableCors({
|
||||
origin: (origin, callback) => {
|
||||
@@ -30,6 +42,9 @@ async function bootstrap() {
|
||||
|
||||
app.enableShutdownHooks();
|
||||
app.useGlobalFilters(new AllExceptionsFilter());
|
||||
app.register(fastifyCookie, {
|
||||
secret: process.env.JWT_SECRET
|
||||
});
|
||||
await app.listen(process.env.PORT ?? 3000, '0.0.0.0', () => { process.env.NODE_ENV !== 'prod' && console.log(`servier is running on ${process.env.PORT}`) });
|
||||
|
||||
}
|
||||
|
||||
@@ -5,19 +5,22 @@ import { JwtService } from '@nestjs/jwt';
|
||||
export class AuthService {
|
||||
constructor(private readonly jwtService: JwtService) {}
|
||||
|
||||
generateTokens(payload: any) {
|
||||
const accessToken = this.jwtService.sign(payload, { expiresIn: '5s' });
|
||||
const refreshToken = this.jwtService.sign({id: payload.id}, { expiresIn: '7d' });
|
||||
generateTokens(id: string) {
|
||||
const accessToken = this.jwtService.sign({id: id}, { expiresIn: '5s' });
|
||||
const refreshToken = this.jwtService.sign({id: id}, { expiresIn: '7d' });
|
||||
|
||||
return { accessToken, refreshToken };
|
||||
}
|
||||
|
||||
refreshTokens(refreshToken: string) {
|
||||
refreshTokens(id: string) {
|
||||
try {
|
||||
const payload = this.jwtService.verify(refreshToken);
|
||||
return this.generateTokens(payload);
|
||||
return this.generateTokens(id);
|
||||
} catch (e) {
|
||||
throw new UnauthorizedException('Invalid Refresh Token');
|
||||
}
|
||||
}
|
||||
|
||||
validateToken(token: string) {
|
||||
return this.jwtService.verify(token);
|
||||
}
|
||||
}
|
||||
@@ -1,26 +1,33 @@
|
||||
import { Injectable, UnauthorizedException } from '@nestjs/common';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
import { PassportStrategy } from '@nestjs/passport';
|
||||
import { FastifyRequest } from 'fastify';
|
||||
import { ExtractJwt, Strategy } from 'passport-jwt';
|
||||
|
||||
const extractJwtFromCookie = (req: FastifyRequest | any): string | null => {
|
||||
if (req.cookies && req.cookies['refresh_token']) {
|
||||
return req.cookies['refresh_token'];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class JwtRefreshStrategy extends PassportStrategy(Strategy, 'refresh-token') {
|
||||
constructor(configService: ConfigService) {
|
||||
super({
|
||||
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
|
||||
jwtFromRequest: ExtractJwt.fromExtractors([extractJwtFromCookie]),
|
||||
secretOrKey: configService.get<string>('JWT_SECRET')!,
|
||||
passReqToCallback: true
|
||||
});
|
||||
}
|
||||
|
||||
async validate(payload: any) {
|
||||
const token = ExtractJwt.fromAuthHeaderAsBearerToken();
|
||||
|
||||
if (!token) throw new UnauthorizedException('Invalid Refresh Token');
|
||||
async validate(req: FastifyRequest, payload: any) {
|
||||
const refreshToken = req.cookies['refresh_token'];
|
||||
if (!refreshToken) throw new UnauthorizedException('Invalid Refresh Token');
|
||||
|
||||
return {
|
||||
id: payload.id,
|
||||
token
|
||||
refreshToken
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,10 @@
|
||||
import { Body, Controller, Get, Headers, Post, Query, Req, UseGuards } from "@nestjs/common";
|
||||
import { Body, Controller, Get, Headers, Post, Query, Req, Res, UseGuards } from "@nestjs/common";
|
||||
import { AccountService } from "./account.service";
|
||||
import * as DTO from "./dto";
|
||||
import { JwtAccessAuthGuard } from "src/middleware/auth/guard/access-token.guard";
|
||||
import { Public } from "src/common/decorators/public.decorator";
|
||||
import { JwtRefreshAuthGuard } from "src/middleware/auth/guard/refresh-token.guard";
|
||||
import type { FastifyReply, FastifyRequest } from "fastify";
|
||||
import { AuthGuard } from "@nestjs/passport";
|
||||
import { JwtAccessAuthGuard } from "src/middleware/auth/guard/access-token.guard";
|
||||
|
||||
@UseGuards(JwtAccessAuthGuard)
|
||||
@Controller('account')
|
||||
@@ -65,18 +66,44 @@ export class AccountController {
|
||||
|
||||
@Public()
|
||||
@Post('login')
|
||||
async login(@Body() body: DTO.LoginRequest): Promise<DTO.LoginResponse> {
|
||||
console.log('a');
|
||||
async login(@Body() body: DTO.LoginRequest, @Res({ passthrough: true }) res: FastifyReply): Promise<DTO.LoginResponse> {
|
||||
const result = await this.accountService.login(body);
|
||||
return result;
|
||||
if (result.success) {
|
||||
res.setCookie('refresh_token', result.refreshToken!, {
|
||||
httpOnly: true,
|
||||
path: '/',
|
||||
secure: true,
|
||||
maxAge: 7 * 24 * 60 * 60 * 1000
|
||||
});
|
||||
}
|
||||
return {
|
||||
success: result.success,
|
||||
message: result.message,
|
||||
error: result.error,
|
||||
accessToken: result.accessToken
|
||||
};
|
||||
}
|
||||
|
||||
@Public()
|
||||
@UseGuards(JwtRefreshAuthGuard)
|
||||
@UseGuards(AuthGuard('refresh-token'))
|
||||
@Get('refresh-access-token')
|
||||
async refreshAccessToken(@Req() req): Promise<DTO.RefreshAccessTokenResponse> {
|
||||
const id = req.user.id;
|
||||
const newAccessToken = this.accountService.refreshAccessToken(id);
|
||||
return newAccessToken;
|
||||
async refreshAccessToken(@Req() req, @Res({ passthrough: true }) res: FastifyReply): Promise<DTO.RefreshAccessTokenResponse> {
|
||||
const result = await this.accountService.refreshAccessToken(req.user.id);
|
||||
if (result.success) {
|
||||
res.setCookie('refresh_token', result.refreshToken!, {
|
||||
httpOnly: true,
|
||||
path: '/',
|
||||
secure: true,
|
||||
maxAge: 7 * 24 * 60 * 60 * 1000
|
||||
});
|
||||
|
||||
return {
|
||||
success: result.success,
|
||||
message: result.message,
|
||||
error: result.error,
|
||||
accessToken: result.accessToken
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -95,13 +95,9 @@ export class AccountService {
|
||||
}
|
||||
|
||||
{
|
||||
const { id, accountId, status, isDeleted, birthday } = queryResult[0];
|
||||
const { id } = queryResult[0];
|
||||
|
||||
const payload = {
|
||||
id, accountId, status, isDeleted, birthday
|
||||
};
|
||||
|
||||
const { accessToken, refreshToken } = this.authService.generateTokens(payload);
|
||||
const { accessToken, refreshToken } = this.authService.generateTokens(id);
|
||||
|
||||
return {
|
||||
success: true,
|
||||
|
||||
@@ -2,5 +2,5 @@ import { BaseResponseDto } from "../base-response.dto";
|
||||
|
||||
export class RefreshAccessTokenResponseDto extends BaseResponseDto{
|
||||
accessToken: string;
|
||||
refreshToken: string;
|
||||
refreshToken?: string;
|
||||
}
|
||||
39
yarn.lock
39
yarn.lock
@@ -1526,6 +1526,16 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@fastify/cookie@npm:^11.0.2":
|
||||
version: 11.0.2
|
||||
resolution: "@fastify/cookie@npm:11.0.2"
|
||||
dependencies:
|
||||
cookie: "npm:^1.0.0"
|
||||
fastify-plugin: "npm:^5.0.0"
|
||||
checksum: 10c0/055aef3260e2a95115e976d820faeacf2513790e99c589c6bfeef06ead181b501a5bd18fb6fa8c507fd2a284cb2e0808e180ab2e64138269f717383e82a75384
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@fastify/cors@npm:11.1.0":
|
||||
version: 11.1.0
|
||||
resolution: "@fastify/cors@npm:11.1.0"
|
||||
@@ -4395,6 +4405,7 @@ __metadata:
|
||||
dependencies:
|
||||
"@eslint/eslintrc": "npm:^3.2.0"
|
||||
"@eslint/js": "npm:^9.18.0"
|
||||
"@fastify/cookie": "npm:^11.0.2"
|
||||
"@nestjs/class-transformer": "npm:^0.4.0"
|
||||
"@nestjs/class-validator": "npm:^0.13.4"
|
||||
"@nestjs/cli": "npm:^11.0.0"
|
||||
@@ -4420,6 +4431,7 @@ __metadata:
|
||||
bcrypt: "npm:^6.0.0"
|
||||
cross-env: "npm:^10.1.0"
|
||||
dotenv: "npm:^17.2.3"
|
||||
dotenv-cli: "npm:^11.0.0"
|
||||
drizzle-kit: "npm:^0.31.7"
|
||||
drizzle-orm: "npm:^0.44.7"
|
||||
eslint: "npm:^9.18.0"
|
||||
@@ -4947,7 +4959,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"cookie@npm:^1.0.1":
|
||||
"cookie@npm:^1.0.0, cookie@npm:^1.0.1":
|
||||
version: 1.1.1
|
||||
resolution: "cookie@npm:1.1.1"
|
||||
checksum: 10c0/79c4ddc0fcad9c4f045f826f42edf54bcc921a29586a4558b0898277fa89fb47be95bc384c2253f493af7b29500c830da28341274527328f18eba9f58afa112c
|
||||
@@ -5132,6 +5144,20 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"dotenv-cli@npm:^11.0.0":
|
||||
version: 11.0.0
|
||||
resolution: "dotenv-cli@npm:11.0.0"
|
||||
dependencies:
|
||||
cross-spawn: "npm:^7.0.6"
|
||||
dotenv: "npm:^17.1.0"
|
||||
dotenv-expand: "npm:^12.0.0"
|
||||
minimist: "npm:^1.2.6"
|
||||
bin:
|
||||
dotenv: cli.js
|
||||
checksum: 10c0/c3e6e58a484b3204eeb167a8f78c9cb04c4bae951069e7860eccbbbf96964e3bd808b3632dfe841e5d882b2c5d77c447f20abd06edd4db623ce719d94a7fb44e
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"dotenv-expand@npm:12.0.1":
|
||||
version: 12.0.1
|
||||
resolution: "dotenv-expand@npm:12.0.1"
|
||||
@@ -5141,6 +5167,15 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"dotenv-expand@npm:^12.0.0":
|
||||
version: 12.0.3
|
||||
resolution: "dotenv-expand@npm:12.0.3"
|
||||
dependencies:
|
||||
dotenv: "npm:^16.4.5"
|
||||
checksum: 10c0/0824bdc74fc816a28b0744b7853a23e046602e9616c82121dfdae21ebc13c6e89afeb773e794e97c35d48be2be0a990fbca721ee3869a49c04210a58a3cf296f
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"dotenv@npm:16.4.7":
|
||||
version: 16.4.7
|
||||
resolution: "dotenv@npm:16.4.7"
|
||||
@@ -5155,7 +5190,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"dotenv@npm:^17.2.3":
|
||||
"dotenv@npm:^17.1.0, dotenv@npm:^17.2.3":
|
||||
version: 17.2.3
|
||||
resolution: "dotenv@npm:17.2.3"
|
||||
checksum: 10c0/c884403209f713214a1b64d4d1defa4934c2aa5b0002f5a670ae298a51e3c3ad3ba79dfee2f8df49f01ae74290fcd9acdb1ab1d09c7bfb42b539036108bb2ba0
|
||||
|
||||
Reference in New Issue
Block a user