Skip to content

Commit

Permalink
allow changing the password when using social logins
Browse files Browse the repository at this point in the history
  • Loading branch information
ZerNico committed May 31, 2023
1 parent 51e6831 commit d385b9f
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
-- DropIndex
DROP INDEX "User_username_key";
2 changes: 1 addition & 1 deletion apps/api/prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ datasource db {

model User {
id String @id @unique
username String @unique
username String
picture String?
email String?
emailVerified Boolean?
Expand Down
19 changes: 19 additions & 0 deletions apps/api/src/logto/management-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ export class ManagementApiClient {
}

public async verifyPassword(userId: string, password: string) {
if (password.length === 0)
throw new LogtoError({ code: 'session.invalid_credentials', message: 'Invalid credentials.' })

const response = await ofetch<LogtoUser>(joinURL(env.LOGTO_URL, 'api', 'users', userId, 'password', 'verify'), {
method: 'POST',
headers: {
Expand Down Expand Up @@ -75,4 +78,20 @@ export class ManagementApiClient {
})
return response
}

public async hasPassword(userId: string) {
const response = await ofetch<{ hasPassword: boolean }>(
joinURL(env.LOGTO_URL, 'api', 'users', userId, 'has-password'),
{
method: 'GET',
headers: {
Authorization: `Bearer ${await this.getToken()}`,
},
}
).catch((err) => {
throw new LogtoError(err.data)
})

return response
}
}
12 changes: 11 additions & 1 deletion apps/api/src/trpc/routes/user/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,17 @@ export const userRouter = router({
)
.mutation(async ({ ctx, input }) => {
try {
await ctx.mm.verifyPassword(ctx.user.id, input.currentPassword)
const [hasPassword, verifyPassword] = await Promise.allSettled([
ctx.mm.hasPassword(ctx.user.id),
ctx.mm.verifyPassword(ctx.user.id, input.currentPassword),
])

if (hasPassword.status === 'rejected') {
throw hasPassword.reason
} else if (verifyPassword.status === 'rejected' && hasPassword.value.hasPassword) {
throw verifyPassword.reason
}

await ctx.mm.updatePassword(ctx.user.id, input.newPassword)
} catch (err) {
if (err instanceof LogtoError && err.code === 'session.invalid_credentials') {
Expand Down
2 changes: 1 addition & 1 deletion apps/web/pages/user/edit-profile/password.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ definePageMeta({
layout: 'auth',
})
const { claims, fetchContext, signIn } = useLogto()
const { claims, signIn } = useLogto()
const { client } = useTRPC()
const { t } = useI18n()
const { notify } = useNotification()
Expand Down

0 comments on commit d385b9f

Please sign in to comment.