Allow email login for new users and auto-provision account on verify
This commit is contained in:
@@ -52,6 +52,20 @@ function invitationToken() {
|
||||
return crypto.randomBytes(24).toString('hex');
|
||||
}
|
||||
|
||||
function buildDefaultFullName(email) {
|
||||
const localPart = email.split('@')[0]?.trim();
|
||||
if (!localPart) {
|
||||
return 'Новый пользователь';
|
||||
}
|
||||
|
||||
return localPart
|
||||
.replace(/[._-]+/g, ' ')
|
||||
.split(' ')
|
||||
.filter(Boolean)
|
||||
.map((part) => part.charAt(0).toUpperCase() + part.slice(1))
|
||||
.join(' ');
|
||||
}
|
||||
|
||||
function formatOrderStatusMessage(order, status, note) {
|
||||
const suffix = note ? `\nКомментарий: ${note}` : '';
|
||||
return `Заказ ${order.code} изменил статус: ${status}.${suffix}`;
|
||||
@@ -263,7 +277,7 @@ export const resolvers = {
|
||||
throw new Error('Code login is supported only for EMAIL channel.');
|
||||
}
|
||||
|
||||
const destination = input.destination.trim();
|
||||
const destination = input.destination.trim().toLowerCase();
|
||||
if (!destination) {
|
||||
throw new Error('Destination is required.');
|
||||
}
|
||||
@@ -277,12 +291,8 @@ export const resolvers = {
|
||||
},
|
||||
});
|
||||
|
||||
if (!user) {
|
||||
throw new Error('User for this destination was not found.');
|
||||
}
|
||||
|
||||
const challenge = createLoginChallenge({
|
||||
userId: user.id,
|
||||
userId: user?.id ?? null,
|
||||
channel: input.channel,
|
||||
destination,
|
||||
});
|
||||
@@ -308,9 +318,25 @@ export const resolvers = {
|
||||
code: input.code,
|
||||
});
|
||||
|
||||
const user = await context.prisma.user.findUnique({
|
||||
let user = challenge.userId
|
||||
? await context.prisma.user.findUnique({
|
||||
where: { id: challenge.userId },
|
||||
})
|
||||
: null;
|
||||
|
||||
if (!user && challenge.channel === 'EMAIL') {
|
||||
const email = String(challenge.destination).trim().toLowerCase();
|
||||
user = await context.prisma.user.upsert({
|
||||
where: { email },
|
||||
update: {},
|
||||
create: {
|
||||
email,
|
||||
fullName: buildDefaultFullName(email),
|
||||
role: 'CLIENT',
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
if (!user) {
|
||||
throw new Error('User is not available for this login challenge.');
|
||||
}
|
||||
@@ -816,4 +842,18 @@ export const resolvers = {
|
||||
RewardWithdrawalRequest: {
|
||||
amount: (tx) => toFloat(tx.amount),
|
||||
},
|
||||
|
||||
User: {
|
||||
company: (user, _, context) => {
|
||||
if (user.company) {
|
||||
return user.company;
|
||||
}
|
||||
if (!user.companyId) {
|
||||
return null;
|
||||
}
|
||||
return context.prisma.company.findUnique({
|
||||
where: { id: user.companyId },
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user