mirror of
https://github.com/MAGICGrants/campaign-site.git
synced 2026-01-09 12:27:59 -05:00
Merge pull request #91 from MAGICGrants/user-update-fix
fix: properly make keycloak user updates
This commit is contained in:
@@ -28,7 +28,16 @@ import Spinner from './Spinner'
|
||||
|
||||
const schema = z
|
||||
.object({
|
||||
name: z.string().min(1),
|
||||
firstName: z
|
||||
.string()
|
||||
.trim()
|
||||
.min(1)
|
||||
.regex(/^[A-Za-záéíóúÁÉÍÓÚñÑçÇ]+$/, 'Use alphabetic characters only.'),
|
||||
lastName: z
|
||||
.string()
|
||||
.trim()
|
||||
.min(1)
|
||||
.regex(/^[A-Za-záéíóúÁÉÍÓÚñÑçÇ]+$/, 'Use alphabetic characters only.'),
|
||||
email: z.string().email(),
|
||||
password: z.string().min(8),
|
||||
confirmPassword: z.string().min(8),
|
||||
@@ -82,19 +91,35 @@ function RegisterFormModal({ close, openLoginModal }: Props) {
|
||||
|
||||
<Form {...form}>
|
||||
<form onSubmit={form.handleSubmit(onSubmit)} className="flex flex-col space-y-4">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="name"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Name</FormLabel>
|
||||
<FormControl>
|
||||
<Input placeholder="John Doe" {...field} />
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
<div className="w-full space-y-4 sm:space-x-2 sm:space-y-0 flex flex-col sm:flex-row">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="firstName"
|
||||
render={({ field }) => (
|
||||
<FormItem className="grow">
|
||||
<FormLabel>First name</FormLabel>
|
||||
<FormControl>
|
||||
<Input placeholder="John" {...field} />
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="lastName"
|
||||
render={({ field }) => (
|
||||
<FormItem className="grow">
|
||||
<FormLabel>Last name</FormLabel>
|
||||
<FormControl>
|
||||
<Input placeholder="Doe" {...field} />
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<FormField
|
||||
control={form.control}
|
||||
|
||||
@@ -51,9 +51,18 @@ export const accountRouter = router({
|
||||
|
||||
await authenticateKeycloakClient()
|
||||
|
||||
const user = await keycloak.users.findOne({ id: userId })
|
||||
|
||||
if (!user || !user.id)
|
||||
throw new TRPCError({
|
||||
code: 'NOT_FOUND',
|
||||
message: 'USER_NOT_FOUND',
|
||||
})
|
||||
|
||||
await keycloak.users.update(
|
||||
{ id: userId },
|
||||
{
|
||||
...user,
|
||||
email,
|
||||
credentials: [{ type: 'password', value: input.newPassword, temporary: false }],
|
||||
}
|
||||
@@ -88,7 +97,7 @@ export const accountRouter = router({
|
||||
if (!emailVerifyTokenVersion) {
|
||||
await keycloak.users.update(
|
||||
{ id: userId },
|
||||
{ email: user.email, attributes: { emailVerifyTokenVersion: 1 } }
|
||||
{ ...user, attributes: { ...user.attributes, emailVerifyTokenVersion: 1 } }
|
||||
)
|
||||
emailVerifyTokenVersion = 1
|
||||
}
|
||||
|
||||
@@ -13,7 +13,16 @@ export const authRouter = router({
|
||||
register: publicProcedure
|
||||
.input(
|
||||
z.object({
|
||||
name: z.string().trim().min(1),
|
||||
firstName: z
|
||||
.string()
|
||||
.trim()
|
||||
.min(1)
|
||||
.regex(/^[A-Za-záéíóúÁÉÍÓÚñÑçÇ]+$/, 'Use alphabetic characters only.'),
|
||||
lastName: z
|
||||
.string()
|
||||
.trim()
|
||||
.min(1)
|
||||
.regex(/^[A-Za-záéíóúÁÉÍÓÚñÑçÇ]+$/, 'Use alphabetic characters only.'),
|
||||
email: z.string().email(),
|
||||
password: z.string(),
|
||||
fundSlug: z.enum(fundSlugs),
|
||||
@@ -31,7 +40,7 @@ export const authRouter = router({
|
||||
credentials: [{ type: 'password', value: input.password, temporary: false }],
|
||||
requiredActions: ['VERIFY_EMAIL'],
|
||||
attributes: {
|
||||
name: input.name,
|
||||
name: `${input.firstName} ${input.lastName}`,
|
||||
passwordResetTokenVersion: 1,
|
||||
emailVerifyTokenVersion: 1,
|
||||
},
|
||||
@@ -107,10 +116,12 @@ export const authRouter = router({
|
||||
await keycloak.users.update(
|
||||
{ id: decoded.userId },
|
||||
{
|
||||
...user,
|
||||
email: decoded.email,
|
||||
emailVerified: true,
|
||||
requiredActions: [],
|
||||
attributes: {
|
||||
...user.attributes,
|
||||
emailVerifyTokenVersion: (emailVerifyTokenVersion + 1).toString(),
|
||||
},
|
||||
}
|
||||
@@ -140,7 +151,11 @@ export const authRouter = router({
|
||||
if (!passwordResetTokenVersion) {
|
||||
await keycloak.users.update(
|
||||
{ id: user.id },
|
||||
{ email: input.email, attributes: { passwordResetTokenVersion: 1 } }
|
||||
{
|
||||
...user,
|
||||
email: input.email,
|
||||
attributes: { ...user.attributes, passwordResetTokenVersion: 1 },
|
||||
}
|
||||
)
|
||||
|
||||
passwordResetTokenVersion = 1
|
||||
@@ -202,7 +217,7 @@ export const authRouter = router({
|
||||
if (!passwordResetTokenVersion) {
|
||||
await keycloak.users.update(
|
||||
{ id: user.id },
|
||||
{ email: user.email, attributes: { passwordResetTokenVersion: 1 } }
|
||||
{ ...user, attributes: { ...user.attributes, passwordResetTokenVersion: 1 } }
|
||||
)
|
||||
|
||||
passwordResetTokenVersion = 1
|
||||
@@ -217,9 +232,11 @@ export const authRouter = router({
|
||||
await keycloak.users.update(
|
||||
{ id: decoded.userId },
|
||||
{
|
||||
...user,
|
||||
email: decoded.email,
|
||||
credentials: [{ type: 'password', value: input.password, temporary: false }],
|
||||
attributes: {
|
||||
...user.attributes,
|
||||
passwordResetTokenVersion: (passwordResetTokenVersion + 1).toString(),
|
||||
},
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ import { Stripe } from 'stripe'
|
||||
import { TRPCError } from '@trpc/server'
|
||||
import { Donation } from '@prisma/client'
|
||||
import { z } from 'zod'
|
||||
import UserRepresentation from '@keycloak/keycloak-admin-client/lib/defs/userRepresentation'
|
||||
|
||||
import { protectedProcedure, publicProcedure, router } from '../trpc'
|
||||
import { CURRENCY, MAX_AMOUNT, MEMBERSHIP_PRICE, MIN_AMOUNT } from '../../config'
|
||||
@@ -30,10 +31,11 @@ export const donationRouter = router({
|
||||
let email = input.email
|
||||
let name = input.name
|
||||
let stripeCustomerId: string | null = null
|
||||
let user: UserRepresentation | null = null
|
||||
|
||||
if (userId) {
|
||||
await authenticateKeycloakClient()
|
||||
const user = await keycloak.users.findOne({ id: userId })!
|
||||
user = (await keycloak.users.findOne({ id: userId })!) || null
|
||||
email = user?.email!
|
||||
name = user?.attributes?.name?.[0]
|
||||
stripeCustomerId = user?.attributes?.[fundSlugToCustomerIdAttr[input.fundSlug]]?.[0] || null
|
||||
@@ -41,7 +43,7 @@ export const donationRouter = router({
|
||||
|
||||
const stripe = _stripe[input.fundSlug]
|
||||
|
||||
if (!stripeCustomerId && userId && email && name) {
|
||||
if (!stripeCustomerId && userId && user && email && name) {
|
||||
const customer = await stripe.customers.create({
|
||||
email,
|
||||
name,
|
||||
@@ -51,7 +53,7 @@ export const donationRouter = router({
|
||||
|
||||
await keycloak.users.update(
|
||||
{ id: userId },
|
||||
{ email: email, attributes: { stripeCustomerId } }
|
||||
{ ...user, attributes: { ...user.attributes, stripeCustomerId } }
|
||||
)
|
||||
}
|
||||
|
||||
@@ -181,6 +183,12 @@ export const donationRouter = router({
|
||||
const email = user?.email!
|
||||
const name = user?.attributes?.name?.[0]!
|
||||
|
||||
if (!user || !user.id)
|
||||
throw new TRPCError({
|
||||
code: 'NOT_FOUND',
|
||||
message: 'USER_NOT_FOUND',
|
||||
})
|
||||
|
||||
let stripeCustomerId =
|
||||
user?.attributes?.[fundSlugToCustomerIdAttr[input.fundSlug]]?.[0] || null
|
||||
|
||||
@@ -189,7 +197,10 @@ export const donationRouter = router({
|
||||
|
||||
stripeCustomerId = customer.id
|
||||
|
||||
await keycloak.users.update({ id: userId }, { email, attributes: { stripeCustomerId } })
|
||||
await keycloak.users.update(
|
||||
{ id: userId },
|
||||
{ ...user, attributes: { ...user.attributes, stripeCustomerId } }
|
||||
)
|
||||
}
|
||||
|
||||
const metadata: DonationMetadata = {
|
||||
|
||||
Reference in New Issue
Block a user