Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

본인인증 정보 덮어쓰기 #2861

Merged
merged 1 commit into from
Dec 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 18 additions & 10 deletions apps/website/src/lib/server/graphql/schemas/user.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { webcrypto } from 'node:crypto';
import dayjs from 'dayjs';
import { and, asc, count, desc, eq, gt, gte, lt, ne, or } from 'drizzle-orm';
import { and, asc, count, desc, eq, gt, gte, lt, or } from 'drizzle-orm';
import { nanoid } from 'nanoid';
import qs from 'query-string';
import * as R from 'radash';
Expand Down Expand Up @@ -1479,19 +1479,17 @@ builder.mutationFields((t) => ({
}

const identities = await database
.select({ id: UserPersonalIdentities.id, userId: UserPersonalIdentities.userId })
.select({ id: UserPersonalIdentities.id, userId: UserPersonalIdentities.userId, ci: UserPersonalIdentities.ci })
.from(UserPersonalIdentities)
.innerJoin(Users, eq(Users.id, UserPersonalIdentities.userId))
.where(
and(
eq(UserPersonalIdentities.ci, resp.response.unique_key),
eq(Users.state, 'ACTIVE'),
ne(UserPersonalIdentities.userId, context.session.userId),
),
);
.where(and(eq(UserPersonalIdentities.ci, resp.response.unique_key), eq(Users.state, 'ACTIVE')));

if (identities.length > 0) {
throw new IntentionalError('이미 인증된 다른 계정이 있어요');
if (identities[0].userId !== context.session.userId) {
throw new IntentionalError('이미 인증된 다른 계정이 있어요');
} else if (identities[0].ci !== resp.response.unique_key) {
throw new IntentionalError('이전 인증과 정보가 달라요 (주민등록번호 변경 시에는 문의해주세요)');
}
}

const [identity] = await database
Expand All @@ -1505,6 +1503,16 @@ builder.mutationFields((t) => ({
ci: resp.response.unique_key,
expiresAt: dayjs().add(1, 'year'),
})
.onConflictDoUpdate({
target: [UserPersonalIdentities.userId],
set: {
kind: 'PHONE',
name: resp.response.name,
birthday: dayjs.kst(resp.response.birthday, 'YYYY-MM-DD'),
phoneNumber: resp.response.phone,
expiresAt: dayjs().add(1, 'year'),
},
})
.returning({ id: UserPersonalIdentities.id });

return identity.id;
Expand Down
43 changes: 30 additions & 13 deletions apps/website/src/lib/server/rest/routes/identification.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ identification.get('/identification/callback', async (_, context) => {

if (resp.response.certified) {
const identity = await database
.select({ userId: UserPersonalIdentities.userId, email: Users.email })
.select({ userId: UserPersonalIdentities.userId, email: Users.email, ci: UserPersonalIdentities.ci })
.from(UserPersonalIdentities)
.innerJoin(Users, eq(Users.id, UserPersonalIdentities.userId))
.where(and(eq(UserPersonalIdentities.ci, resp.response.unique_key), eq(Users.state, 'ACTIVE')))
Expand All @@ -54,20 +54,37 @@ identification.get('/identification/callback', async (_, context) => {
headers: { Location: '/find-account/complete' },
});
} else if (context.session) {
if (identity && identity.userId !== context.session.userId) {
context.flash('error', '이미 인증된 다른 계정이 있어요');
return status(303, { headers: { Location: '/me/settings' } });
if (identity) {
if (identity.userId !== context.session.userId) {
context.flash('error', '이미 인증된 다른 계정이 있어요');
return status(303, { headers: { Location: '/me/settings' } });
} else if (identity.ci !== resp.response.unique_key) {
context.flash('error', '이전 인증과 정보가 달라요 (주민등록번호 변경 시에는 문의해주세요)');
return status(303, { headers: { Location: '/me/settings' } });
}
}

await database.insert(UserPersonalIdentities).values({
userId: context.session.userId,
kind: 'PHONE',
name: resp.response.name,
birthday: dayjs.kst(resp.response.birthday, 'YYYY-MM-DD'),
phoneNumber: resp.response.phone,
ci: resp.response.unique_key,
expiresAt: dayjs().add(1, 'year'),
});
await database
.insert(UserPersonalIdentities)
.values({
userId: context.session.userId,
kind: 'PHONE',
name: resp.response.name,
birthday: dayjs.kst(resp.response.birthday, 'YYYY-MM-DD'),
phoneNumber: resp.response.phone,
ci: resp.response.unique_key,
expiresAt: dayjs().add(1, 'year'),
})
.onConflictDoUpdate({
target: [UserPersonalIdentities.userId],
set: {
kind: 'PHONE',
name: resp.response.name,
birthday: dayjs.kst(resp.response.birthday, 'YYYY-MM-DD'),
phoneNumber: resp.response.phone,
expiresAt: dayjs().add(1, 'year'),
},
});

await context.flash('success', '본인인증이 완료되었어요');
}
Expand Down
13 changes: 5 additions & 8 deletions apps/website/src/lib/server/utils/age.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import dayjs from 'dayjs';
import { and, desc, gt, inArray } from 'drizzle-orm';
import { inArray } from 'drizzle-orm';
import * as R from 'radash';
import * as E from '$lib/enums';
import { database, UserPersonalIdentities } from '../database';
Expand Down Expand Up @@ -37,10 +37,11 @@ const getBirthdayAge = (birthday?: dayjs.Dayjs) => {
return age;
};

type AgeIdentity = Pick<typeof UserPersonalIdentities.$inferSelect, 'kind' | 'birthday'>;
type AgeIdentity = Pick<typeof UserPersonalIdentities.$inferSelect, 'kind' | 'birthday' | 'expiresAt'>;

const allowedAgeRating = (identity: AgeIdentity | undefined): (keyof typeof E.PostAgeRating)[] => {
if (!identity) {
if (!identity || identity.expiresAt?.isBefore(dayjs())) {
// expiresAt null이면 유효기간 없는 사람 (개발자계정일듯...)
return ['ALL'];
}

Expand All @@ -64,11 +65,7 @@ export const getPersonalIdentity = async (userId: string | undefined, context: P
name: 'UserPersonalIdentities(userId)',
nullable: true,
load: async (userIds: string[]) => {
return database
.selectDistinctOn([UserPersonalIdentities.userId])
.from(UserPersonalIdentities)
.where(and(inArray(UserPersonalIdentities.userId, userIds), gt(UserPersonalIdentities.expiresAt, dayjs())))
.orderBy(UserPersonalIdentities.userId, desc(UserPersonalIdentities.createdAt));
return database.select().from(UserPersonalIdentities).where(inArray(UserPersonalIdentities.userId, userIds));
},

key: (identity) => identity?.userId,
Expand Down
Loading