Skip to content

Commit

Permalink
fix login
Browse files Browse the repository at this point in the history
  • Loading branch information
arily committed Oct 26, 2023
1 parent db0c16e commit 2a57399
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 46 deletions.
13 changes: 9 additions & 4 deletions src/server/backend/$base/server/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,18 @@ export namespace UserProvider {
export abstract class UserProvider<Id> extends IdTransformable {
abstract exists({ handle, keys }: UserProvider.OptType): PromiseLike<boolean>

abstract getCompact<_Scope extends Scope>(
opt: UserProvider.OptType & { scope: _Scope }
abstract getCompact(
opt: UserProvider.OptType & { scope: Scope }
): Promise<UserCompact<Id>>

abstract getCompactById<_Scope extends Scope>(opt: {
abstract testPassword(
opt: UserProvider.OptType & { scope: Scope },
hashedPassowrd: string,
): Promise<UserCompact<Id>>

abstract getCompactById(opt: {
id: Id
scope: _Scope
scope: Scope
}): Promise<UserCompact<Id>>

abstract getStatistics(query: {
Expand Down
1 change: 0 additions & 1 deletion src/server/backend/bancho.py/db-query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ export const userCompacts: Prisma.UserFindManyArgs = {
safeName: true,
country: true,
priv: true,
pwBcrypt: true,
email: true,
},
} as const satisfies {
Expand Down
31 changes: 25 additions & 6 deletions src/server/backend/bancho.py/server/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { glob } from 'glob'
import imageType from 'image-type'
import type { Prisma, Stat } from 'prisma-client-bancho-py'
import { merge } from 'lodash-es'
import bcrypt from 'bcryptjs'
import { BanchoPyMode, BanchoPyScoreStatus } from '../enums'
import {
BPyMode,
Expand All @@ -21,7 +22,6 @@ import {
toRankingSystemScores,
toSafeName,
toUserCompact,
toUserSecrets,
} from '../transforms'

import {
Expand All @@ -42,7 +42,7 @@ import { UserRelationProvider } from './user-relations'
import { ArticleProvider } from './article'
import { ScoreProvider } from './score'
import type { ExtractLocationSettings, ExtractSettingType } from '$base/@define-setting'
import { userNotFound } from '~/server/trpc/messages'
import { passwordMismatch, userNotFound } from '~/server/trpc/messages'

import { UserProvider as Base } from '$base/server'
import type { ActiveMode, ActiveRuleset, LeaderboardRankingSystem } from '~/def/common'
Expand All @@ -52,6 +52,8 @@ import { Scope, UserStatus } from '~/def/user'
import { Mode, Rank, Ruleset } from '~/def'
import type { CountryCode } from '~/def/country-code'

const { compare } = bcrypt

type ServerSetting = ExtractSettingType<ExtractLocationSettings<DynamicSettingStore.Server, typeof settings>>

const logger = Logger.child({ label: 'user' })
Expand Down Expand Up @@ -143,9 +145,7 @@ class DBUserProvider extends Base<Id> implements Base<Id> {
return toUserCompact(user, this.config)
}

async getCompact<
_Scope extends Scope = Scope.Public,
>(opt: Base.OptType & { scope?: _Scope }) {
async getCompact(opt: Base.OptType & { scope?: Scope }) {
const { handle, scope, keys } = opt
/* optimized */
const user = await this.db.user.findFirstOrThrow({
Expand All @@ -169,7 +169,26 @@ class DBUserProvider extends Base<Id> implements Base<Id> {
.catch(() => {
throw new TRPCError({ code: 'NOT_FOUND', message: userNotFound })
})
return Object.assign(toUserCompact(user, this.config), toUserSecrets(user))
return toUserCompact(user, this.config)
}

async testPassword(opt: Base.OptType, hashedPassword: string) {
const user = await this.db.user.findFirstOrThrow({
where: {
...createUserHandleWhereQuery({
handle: opt.handle,
selectAgainst: ['id', 'name', 'safeName', 'email'],
}),
},
})
const result = await compare(hashedPassword, user.pwBcrypt)
if (!result) {
throw new TRPCError({
code: 'UNAUTHORIZED',
message: passwordMismatch,
})
}
return toUserCompact(user, this.config)
}

// https://github.com/prisma/prisma/issues/6570 need two separate query to get count for now
Expand Down
25 changes: 4 additions & 21 deletions src/server/trpc/routers/me.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
import { TRPCError } from '@trpc/server'
import { nativeEnum, z } from 'zod'

import bcrypt from 'bcryptjs'

import {
atLeastOneUserNotExists,
oldPasswordMismatch,
relationTypeNotFound,
userExists,
} from '../messages'
Expand All @@ -20,8 +17,6 @@ import { CountryCode } from '~/def/country-code'
import { DynamicSettingStore, Scope } from '~/def/user'
import { Mode, Ruleset } from '~/def'

const { compare } = bcrypt

// const verifiedEmail = new Map<string, Set<string>>()
export const router = _router({
settings: pUser.query(async ({ ctx }) => {
Expand Down Expand Up @@ -108,24 +103,12 @@ export const router = _router({
}),
)
.mutation(async ({ ctx, input }) => {
const userWithPassword = await users.getCompactById({
id: ctx.user.id,
scope: Scope.Self,
})
if (
!(await compare(
input.oldPassword,
userWithPassword.password,
))
) {
throw new TRPCError({
code: 'UNAUTHORIZED',
message: oldPasswordMismatch,
})
}
const ok = await users.testPassword({
handle: ctx.user.id.toString(),
}, input.oldPassword)

return await users.changePassword(
userWithPassword,
ok,
input.newPassword,
)
}),
Expand Down
15 changes: 1 addition & 14 deletions src/server/trpc/routers/session.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import { TRPCError } from '@trpc/server'
import bcrypt from 'bcryptjs'
import { z } from 'zod'

import {
passwordMismatch,
sessionNotFound,
unableToRetrieveSession,
unknownError,
Expand All @@ -15,7 +13,6 @@ import { Constant } from '../../common/constants'
import { sessions, users } from '~/server/singleton/service'
import { Logger } from '$base/logger'
import { UserProvider } from '$active/server'
import { Scope } from '~/def/user'

const logger = Logger.child({ label: 'session', backend: 'transport', transport: 'trpc' })

Expand All @@ -29,24 +26,14 @@ export const router = _router({
)
.query(async ({ input: { handle, md5HashedPassword }, ctx }) => {
try {
const user = await users.getCompact({
handle,
scope: Scope.Self,
})
const result = await bcrypt.compare(md5HashedPassword, user.password)
if (!result) {
throw new TRPCError({
code: 'UNAUTHORIZED',
message: passwordMismatch,
})
}
const session = await ctx.session.getBinding()
if (!session) {
throw new TRPCError({
code: 'INTERNAL_SERVER_ERROR',
message: unableToRetrieveSession,
})
}
const user = await users.testPassword({ handle }, md5HashedPassword)
const newSessionId = await sessions.update(ctx.session.id, { userId: UserProvider.idToString(user.id) })
if (newSessionId && newSessionId !== ctx.session.id) {
setCookie(ctx.h3Event, Constant.SessionLabel, newSessionId, { httpOnly: true })
Expand Down

0 comments on commit 2a57399

Please sign in to comment.