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');
|
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) {
|
function formatOrderStatusMessage(order, status, note) {
|
||||||
const suffix = note ? `\nКомментарий: ${note}` : '';
|
const suffix = note ? `\nКомментарий: ${note}` : '';
|
||||||
return `Заказ ${order.code} изменил статус: ${status}.${suffix}`;
|
return `Заказ ${order.code} изменил статус: ${status}.${suffix}`;
|
||||||
@@ -263,7 +277,7 @@ export const resolvers = {
|
|||||||
throw new Error('Code login is supported only for EMAIL channel.');
|
throw new Error('Code login is supported only for EMAIL channel.');
|
||||||
}
|
}
|
||||||
|
|
||||||
const destination = input.destination.trim();
|
const destination = input.destination.trim().toLowerCase();
|
||||||
if (!destination) {
|
if (!destination) {
|
||||||
throw new Error('Destination is required.');
|
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({
|
const challenge = createLoginChallenge({
|
||||||
userId: user.id,
|
userId: user?.id ?? null,
|
||||||
channel: input.channel,
|
channel: input.channel,
|
||||||
destination,
|
destination,
|
||||||
});
|
});
|
||||||
@@ -308,9 +318,25 @@ export const resolvers = {
|
|||||||
code: input.code,
|
code: input.code,
|
||||||
});
|
});
|
||||||
|
|
||||||
const user = await context.prisma.user.findUnique({
|
let user = challenge.userId
|
||||||
|
? await context.prisma.user.findUnique({
|
||||||
where: { id: challenge.userId },
|
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) {
|
if (!user) {
|
||||||
throw new Error('User is not available for this login challenge.');
|
throw new Error('User is not available for this login challenge.');
|
||||||
}
|
}
|
||||||
@@ -816,4 +842,18 @@ export const resolvers = {
|
|||||||
RewardWithdrawalRequest: {
|
RewardWithdrawalRequest: {
|
||||||
amount: (tx) => toFloat(tx.amount),
|
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