Skip to content

Commit

Permalink
[ST-464] πŸ” User DB ꡬ쑰 λ³€κ²½ (#41)
Browse files Browse the repository at this point in the history
* πŸ” User ν…Œμ΄λΈ” ꡬ쑰 λ³€κ²½

* πŸ” UserId 기반 λ³€κ²½
  • Loading branch information
w8385 authored Aug 7, 2023
1 parent ee93416 commit faaf768
Show file tree
Hide file tree
Showing 19 changed files with 172 additions and 219 deletions.
1 change: 0 additions & 1 deletion src/agora/agora.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ export class AgoraService {
},
),
);
console.log('whiteboard token ', data);
if (data?.uuid === undefined) {
return null;
}
Expand Down
4 changes: 1 addition & 3 deletions src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ import { QuestionModule } from './question/question.module';
import { OfferModule } from './offer/offer.module';
import { AuthMiddleware } from './auth/auth.middleware';
import { HttpModule } from '@nestjs/axios';
import { JwtService } from '@nestjs/jwt';
import { AuthRepository } from './auth/auth.repository';

@Module({
imports: [
Expand All @@ -33,7 +31,7 @@ import { AuthRepository } from './auth/auth.repository';
// ReviewModule,
],
controllers: [AppController],
providers: [AppService, AuthRepository, JwtService],
providers: [AppService],
})
export class AppModule implements NestModule {
configure(consumer: MiddlewareConsumer) {
Expand Down
1 change: 0 additions & 1 deletion src/auth/auth.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ export class AuthController {
@ApiResponse(AuthResponse.verifyJwt)
@Get('token/verify')
verifyJwt(@Query('jwt') jwt: string) {
console.log(jwt);
return this.authService.verifyJwt(jwt);
}

Expand Down
4 changes: 2 additions & 2 deletions src/auth/auth.middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ export class AuthMiddleware implements NestMiddleware {
next();
}
try {
const { vendor, userId } = await this.authRepository.decodeJwt(jwt);
req.headers['vendor'] = vendor;
const { userId, role } = await this.authRepository.decodeJwt(jwt);
req.headers['userId'] = userId;
req.headers['role'] = role;
next();
} catch (error) {
next();
Expand Down
7 changes: 6 additions & 1 deletion src/auth/auth.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ import { AuthController } from './auth.controller';
import { HttpModule } from '@nestjs/axios';
import { DynamooseModule } from 'nestjs-dynamoose';
import { UserSchema } from '../user/entities/user.schema';
import { UploadRepository } from '../upload/upload.repository';
import { UserRepository } from '../user/user.repository';
import { AuthRepository } from './auth.repository';
import { JwtService } from '@nestjs/jwt';
import { AuthSchema } from './entities/auth.schema';
import { UploadRepository } from '../upload/upload.repository';

@Module({
imports: [
Expand All @@ -17,6 +18,10 @@ import { JwtService } from '@nestjs/jwt';
name: 'User',
schema: UserSchema,
},
{
name: 'Auth',
schema: AuthSchema,
},
]),
],
controllers: [AuthController],
Expand Down
75 changes: 57 additions & 18 deletions src/auth/auth.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@ import { firstValueFrom } from 'rxjs';
import { UserRepository } from '../user/user.repository';
import * as process from 'process';
import { JwtService } from '@nestjs/jwt';
import { Auth, AuthKey } from './entities/auth.interface';
import { InjectModel, Model } from 'nestjs-dynamoose';

@Injectable()
export class AuthRepository {
constructor(
@InjectModel('Auth') private readonly authModel: Model<Auth, AuthKey>,
private readonly httpService: HttpService,
private readonly jwtService: JwtService,
private readonly userRepository: UserRepository,
Expand All @@ -19,12 +22,11 @@ export class AuthRepository {
const accessToken = await this.getAccessToken(vendor, code);

const userId = await this.getUserIdFromAccessToken(vendor, accessToken);
const user = await this.userRepository.get({ vendor, userId });
const user = await this.userRepository.get(userId);
const role = user.role;

const jwt = this.jwtService.sign(
{
vendor,
userId,
role,
},
Expand All @@ -43,11 +45,10 @@ export class AuthRepository {
}
}

async signJwt(vendor: string, userId: string, role: string) {
async signJwt(userId: string, role: string) {
try {
return this.jwtService.sign(
{
vendor,
userId,
role,
},
Expand All @@ -65,7 +66,6 @@ export class AuthRepository {
try {
const decoded = this.jwtService.decode(jwt);
return {
vendor: decoded['vendor'],
userId: decoded['userId'],
role: decoded['role'],
iat: decoded['iat'],
Expand All @@ -82,7 +82,6 @@ export class AuthRepository {
secret: process.env.JWT_SECRET_KEY,
});
return {
vendor: verified['vendor'],
userId: verified['userId'],
role: verified['role'],
iat: verified['iat'],
Expand Down Expand Up @@ -132,7 +131,7 @@ export class AuthRepository {
'https://kapi.kakao.com/v1/user/access_token_info',
{
headers: {
Authorization: `${accessToken}`,
Authorization: accessToken,
},
},
),
Expand All @@ -156,25 +155,65 @@ export class AuthRepository {
}),
);

return data.id.toString();
const authId = data.id.toString();
const auth = await this.authModel.get({
vendor,
authId,
});
return auth.userId;
} catch (error) {
throw new Error('μ‚¬μš©μžλ₯Ό 찾을 수 μ—†μŠ΅λ‹ˆλ‹€.');
}
}
}

async getUserFromAccessToken(vendor: string, accessToken: string) {
if (vendor === 'kakao') {
try {
const userId = await this.getUserIdFromAccessToken(vendor, accessToken);
try {
const userId = await this.getUserIdFromAccessToken(vendor, accessToken);

return await this.userRepository.get({
vendor,
userId,
});
} catch (error) {
throw new Error('μ‚¬μš©μžλ₯Ό 찾을 수 μ—†μŠ΅λ‹ˆλ‹€.');
}
return await this.userRepository.get(userId);
} catch (error) {
throw new Error('μ‚¬μš©μžλ₯Ό 찾을 수 μ—†μŠ΅λ‹ˆλ‹€.');
}
}

async createAuth(
vendor: string,
authId: string,
userId: string,
role: string,
) {
try {
return await this.authModel.create({
vendor,
authId,
userId,
role,
});
} catch (error) {
throw new Error('인증정보λ₯Ό μƒμ„±ν•˜λŠ”λ° μ‹€νŒ¨ν–ˆμŠ΅λ‹ˆλ‹€.');
}
}

async getAuth(vendor: string, authId: string) {
try {
return await this.authModel.get({
vendor,
authId,
});
} catch (error) {
throw new Error('인증정보λ₯Ό κ°€μ Έμ˜€λŠ”λ° μ‹€νŒ¨ν–ˆμŠ΅λ‹ˆλ‹€.');
}
}

async getUserIdFromAuth(vendor: string, authId: string) {
const auth = await this.getAuth(vendor, authId);
if (auth === undefined) {
throw new Error('인증정보λ₯Ό 찾을 수 μ—†μŠ΅λ‹ˆλ‹€.');
}

return auth.userId;
}

async delete(userId: string) {}
}
2 changes: 1 addition & 1 deletion src/auth/auth.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ export class AuthService {
vendor,
accessToken,
);
return new Success('μ„±κ³΅μ μœΌλ‘œ μ‚¬μš©μž IDλ₯Ό κ°€μ Έμ™”μŠ΅λ‹ˆλ‹€.', userId);
return new Success('μ„±κ³΅μ μœΌλ‘œ μ‚¬μš©μž IDλ₯Ό κ°€μ Έμ™”μŠ΅λ‹ˆλ‹€.', { userId });
} catch (error) {
return new Fail(error.message);
}
Expand Down
4 changes: 4 additions & 0 deletions src/auth/entities/auth.entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,8 @@ export class AccessToken {
static userKey(headers: Headers) {
return { vendor: headers['vendor'], userId: headers['userId'] };
}

static userId(headers: Headers) {
return headers['userId'];
}
}
9 changes: 9 additions & 0 deletions src/auth/entities/auth.interface.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export interface AuthKey {
vendor: string;
authId: string;
}

export interface Auth extends AuthKey {
userId: string;
role: string;
}
18 changes: 18 additions & 0 deletions src/auth/entities/auth.schema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Schema } from 'dynamoose';

export const AuthSchema = new Schema({
vendor: {
type: String,
hashKey: true,
},
authId: {
type: String,
rangeKey: true,
},
userId: {
type: String,
},
role: {
type: String,
},
});
12 changes: 2 additions & 10 deletions src/offer/offer.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ export class OfferRepository {
) {
try {
const teacher = await this.userModel.get({
vendor: userKey.vendor,
id: userKey.userId,
});

Expand Down Expand Up @@ -48,7 +47,6 @@ export class OfferRepository {
questionId: string,
) {
const user = await this.userModel.get({
vendor: userKey.vendor,
id: userKey.userId,
});
if (user === undefined) {
Expand All @@ -67,10 +65,7 @@ export class OfferRepository {
const teachers = question.teacherIds.map(async (teacherId) => {
const vendor = teacherId.split('#')[0];
const id = teacherId.split('#')[1];
return await this.userModel.get({
vendor,
id,
});
return await this.userModel.get({ id });
});
return await Promise.all(teachers);
}
Expand Down Expand Up @@ -129,10 +124,7 @@ export class OfferRepository {
questionId: string,
teacherId: string,
) {
const user: User = await this.userModel.get({
vendor: userKey.vendor,
id: userKey.userId,
});
const user: User = await this.userModel.get({ id: userKey.userId });
if (user === undefined) {
throw new Error('μ‚¬μš©μžλ₯Ό 찾을 수 μ—†μŠ΅λ‹ˆλ‹€.');
} else if (user.role === 'teacher') {
Expand Down
54 changes: 20 additions & 34 deletions src/question/question.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { InjectModel, Model } from 'nestjs-dynamoose';
import { Question, QuestionKey } from './entities/question.interface';
import { CreateQuestionDto } from './dto/create-question.dto';
import { User, UserKey } from '../user/entities/user.interface';
import { HttpErrorByCode } from '@nestjs/common/utils/http-error-by-code.util';

@Injectable()
export class QuestionRepository {
Expand All @@ -20,18 +19,11 @@ export class QuestionRepository {
createQuestionDto: CreateQuestionDto,
problemImage: string,
): Promise<Question> {
let user: User;
try {
user = await this.userModel.get({
vendor: userKey.vendor,
id: userKey.userId,
});
} catch (error) {
throw new ErrorEvent['404']('μ‚¬μš©μžλ₯Ό 찾을 수 μ—†μŠ΅λ‹ˆλ‹€.');
}

if (user.role === 'teacher') {
throw new ErrorEvent['403']('μ„ μƒλ‹˜μ€ μ§ˆλ¬Έμ„ 생성할 수 μ—†μŠ΅λ‹ˆλ‹€.');
const user: User = await this.userModel.get({ id: userKey.userId });
if (user === undefined) {
throw new Error('μ‚¬μš©μžλ₯Ό 찾을 수 μ—†μŠ΅λ‹ˆλ‹€.');
} else if (user.role === 'teacher') {
throw new Error('μ„ μƒλ‹˜μ€ μ§ˆλ¬Έμ„ 생성할 수 μ—†μŠ΅λ‹ˆλ‹€.');
}

try {
Expand All @@ -55,7 +47,7 @@ export class QuestionRepository {
createdAt: new Date().toISOString(),
});
} catch (error) {
throw new HttpErrorByCode['400']('μ§ˆλ¬Έμ„ 생성할 수 μ—†μŠ΅λ‹ˆλ‹€.');
throw new Error('μ§ˆλ¬Έμ„ 생성할 수 μ—†μŠ΅λ‹ˆλ‹€.');
}
}

Expand All @@ -76,35 +68,29 @@ export class QuestionRepository {
userKey: { vendor: string; userId: string },
questionId: string,
) {
let user: User;
try {
user = await this.userModel.get({
vendor: userKey.vendor,
id: userKey.userId,
});
} catch (error) {
throw new ErrorEvent['404']('μ‚¬μš©μžλ₯Ό 찾을 수 μ—†μŠ΅λ‹ˆλ‹€.');
const user: User = await this.userModel.get({ id: userKey.userId });
if (user === undefined) {
throw new Error('μ‚¬μš©μžλ₯Ό 찾을 수 μ—†μŠ΅λ‹ˆλ‹€.');
} else if (user.role === 'teacher') {
throw new Error('μ„ μƒλ‹˜μ€ μ§ˆλ¬Έμ„ μ‚­μ œν•  수 μ—†μŠ΅λ‹ˆλ‹€.');
}

if (user.role === 'teacher') {
throw new ErrorEvent['403']('μ„ μƒλ‹˜μ€ μ§ˆλ¬Έμ„ μ‚­μ œν•  수 μ—†μŠ΅λ‹ˆλ‹€.');
const question: Question = await this.questionModel.get({
id: questionId,
});
if (
question.student.id !== userKey.userId ||
question.student.vendor !== userKey.vendor
) {
return new Error('μ§ˆλ¬Έμ„ μ‚­μ œν•  κΆŒν•œμ΄ μ—†μŠ΅λ‹ˆλ‹€.');
}

try {
const question: Question = await this.questionModel.get({
id: questionId,
});
if (
question.student.id !== userKey.userId ||
question.student.vendor !== userKey.vendor
) {
return new ErrorEvent['403']('μ§ˆλ¬Έμ„ μ‚­μ œν•  κΆŒν•œμ΄ μ—†μŠ΅λ‹ˆλ‹€.');
}
return await this.questionModel.delete({
id: questionId,
});
} catch (error) {
throw new ErrorEvent['400']('μ§ˆλ¬Έμ„ μ‚­μ œν•  수 μ—†μŠ΅λ‹ˆλ‹€.');
throw new Error('μ§ˆλ¬Έμ„ μ‚­μ œν•  수 μ—†μŠ΅λ‹ˆλ‹€.');
}
}
}
Loading

0 comments on commit faaf768

Please sign in to comment.