Merge branch 'staging' of https://github.com/VAR-Virtual-Air-Rescue/var-monorepo into staging
This commit is contained in:
@@ -92,6 +92,11 @@ export default function AdminPanel() {
|
|||||||
|
|
||||||
const modalRef = useRef<HTMLDialogElement>(null);
|
const modalRef = useRef<HTMLDialogElement>(null);
|
||||||
|
|
||||||
|
console.debug("piloten von API", {
|
||||||
|
anzahl: pilots?.length,
|
||||||
|
pilots,
|
||||||
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<button
|
<button
|
||||||
@@ -108,11 +113,11 @@ export default function AdminPanel() {
|
|||||||
<form method="dialog">
|
<form method="dialog">
|
||||||
<button className="btn btn-sm btn-circle btn-ghost absolute right-2 top-2">✕</button>
|
<button className="btn btn-sm btn-circle btn-ghost absolute right-2 top-2">✕</button>
|
||||||
</form>
|
</form>
|
||||||
<h3 className="font-bold text-lg flex items-center gap-2">
|
<h3 className="flex items-center gap-2 text-lg font-bold">
|
||||||
<Shield size={22} /> Admin Panel
|
<Shield size={22} /> Admin Panel
|
||||||
</h3>
|
</h3>
|
||||||
<div className="flex gap-2 mt-4 w-full">
|
<div className="mt-4 flex w-full gap-2">
|
||||||
<div className="card bg-base-300 shadow-md w-full h-96 overflow-y-auto">
|
<div className="card bg-base-300 h-96 w-full overflow-y-auto shadow-md">
|
||||||
<div className="card-body">
|
<div className="card-body">
|
||||||
<div className="card-title flex items-center gap-2">
|
<div className="card-title flex items-center gap-2">
|
||||||
<UserCheck size={20} /> Verbundene Clients
|
<UserCheck size={20} /> Verbundene Clients
|
||||||
|
|||||||
@@ -73,7 +73,10 @@ export const ProfileForm: React.FC<ProfileFormProps> = ({ user }: ProfileFormPro
|
|||||||
className="card-body"
|
className="card-body"
|
||||||
onSubmit={form.handleSubmit(async (values) => {
|
onSubmit={form.handleSubmit(async (values) => {
|
||||||
if (!values.id) return;
|
if (!values.id) return;
|
||||||
await editUser(values.id, values);
|
await editUser(values.id, {
|
||||||
|
...values,
|
||||||
|
email: values.email.toLowerCase(),
|
||||||
|
});
|
||||||
form.reset(values);
|
form.reset(values);
|
||||||
toast.success("Deine Änderungen wurden gespeichert!", {
|
toast.success("Deine Änderungen wurden gespeichert!", {
|
||||||
style: {
|
style: {
|
||||||
|
|||||||
@@ -91,7 +91,10 @@ export const ProfileForm = ({
|
|||||||
className="card-body"
|
className="card-body"
|
||||||
onSubmit={form.handleSubmit(async (values) => {
|
onSubmit={form.handleSubmit(async (values) => {
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
await updateUser(values);
|
await updateUser({
|
||||||
|
...values,
|
||||||
|
email: values.email.toLowerCase(),
|
||||||
|
});
|
||||||
if (discordAccount) {
|
if (discordAccount) {
|
||||||
await setStandardName({
|
await setStandardName({
|
||||||
memberId: discordAccount.discordId,
|
memberId: discordAccount.discordId,
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ export const Login = () => {
|
|||||||
try {
|
try {
|
||||||
const data = await signIn("credentials", {
|
const data = await signIn("credentials", {
|
||||||
redirect: false,
|
redirect: false,
|
||||||
email: form.getValues("email"),
|
email: form.getValues("email").toLowerCase(),
|
||||||
password: form.getValues("password"),
|
password: form.getValues("password"),
|
||||||
});
|
});
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
@@ -62,12 +62,12 @@ export const Login = () => {
|
|||||||
Registrierung
|
Registrierung
|
||||||
</Link>
|
</Link>
|
||||||
</span>
|
</span>
|
||||||
<div className="alert alert-info alert-outline text-sm font-semibold text-center justify-center">
|
<div className="alert alert-info alert-outline justify-center text-center text-sm font-semibold">
|
||||||
Du warst bereits Nutzer der V1? <br />
|
Du warst bereits Nutzer der V1? <br />
|
||||||
Melde dich mit deinen alten Zugangsdaten an.
|
Melde dich mit deinen alten Zugangsdaten an.
|
||||||
</div>
|
</div>
|
||||||
<div className="mt-5 mb-2">
|
<div className="mb-2 mt-5">
|
||||||
<label className="input input-bordered flex items-center gap-2 w-full">
|
<label className="input input-bordered flex w-full items-center gap-2">
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
viewBox="0 0 16 16"
|
viewBox="0 0 16 16"
|
||||||
@@ -84,7 +84,7 @@ export const Login = () => {
|
|||||||
? form.formState.errors.email.message
|
? form.formState.errors.email.message
|
||||||
: ""}
|
: ""}
|
||||||
</p>
|
</p>
|
||||||
<label className="input input-bordered flex items-center gap-2 mt-2 w-full">
|
<label className="input input-bordered mt-2 flex w-full items-center gap-2">
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
viewBox="0 0 16 16"
|
viewBox="0 0 16 16"
|
||||||
@@ -105,8 +105,8 @@ export const Login = () => {
|
|||||||
className="grow"
|
className="grow"
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
<span className="text-sm font-medium flex justify-end">
|
<span className="flex justify-end text-sm font-medium">
|
||||||
<Link href="/passwort-reset" className="link link-accent link-hover ">
|
<Link href="/passwort-reset" className="link link-accent link-hover">
|
||||||
Passwort vergessen?
|
Passwort vergessen?
|
||||||
</Link>
|
</Link>
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ export const PasswortReset = () => {
|
|||||||
onSubmit={form.handleSubmit(async () => {
|
onSubmit={form.handleSubmit(async () => {
|
||||||
try {
|
try {
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
const { error } = await resetPassword(form.getValues().email);
|
const { error } = await resetPassword(form.getValues().email.toLowerCase());
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
@@ -56,7 +56,7 @@ export const PasswortReset = () => {
|
|||||||
<Toaster position="top-center" reverseOrder={false} />
|
<Toaster position="top-center" reverseOrder={false} />
|
||||||
</div>
|
</div>
|
||||||
<h1 className="text-3xl font-bold">Passwort zurücksetzen</h1>
|
<h1 className="text-3xl font-bold">Passwort zurücksetzen</h1>
|
||||||
<label className="input input-bordered flex items-center gap-2 w-full">
|
<label className="input input-bordered flex w-full items-center gap-2">
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
viewBox="0 0 16 16"
|
viewBox="0 0 16 16"
|
||||||
@@ -73,8 +73,8 @@ export const PasswortReset = () => {
|
|||||||
? form.formState.errors.email.message
|
? form.formState.errors.email.message
|
||||||
: ""}
|
: ""}
|
||||||
</p>
|
</p>
|
||||||
<span className="text-sm font-medium flex justify-end">
|
<span className="flex justify-end text-sm font-medium">
|
||||||
<Link href="/login" className="link link-accent link-hover ">
|
<Link href="/login" className="link link-accent link-hover">
|
||||||
zum Login
|
zum Login
|
||||||
</Link>
|
</Link>
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ export const resetPassword = async (email: string) => {
|
|||||||
email,
|
email,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const oldUser = (OLD_USER as OldUser[]).find((u) => u.email.toLowerCase() === email.toLowerCase());
|
const oldUser = (OLD_USER as OldUser[]).find((u) => u.email.toLowerCase() === email);
|
||||||
if (!user) {
|
if (!user) {
|
||||||
if (oldUser) {
|
if (oldUser) {
|
||||||
user = await createNewUserFromOld(oldUser);
|
user = await createNewUserFromOld(oldUser);
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ export const Register = () => {
|
|||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
const values = form.getValues();
|
const values = form.getValues();
|
||||||
const user = await register({
|
const user = await register({
|
||||||
email: form.getValues("email"),
|
email: form.getValues("email").toLowerCase(),
|
||||||
password: form.getValues("password"),
|
password: form.getValues("password"),
|
||||||
firstname: form.getValues("firstname"),
|
firstname: form.getValues("firstname"),
|
||||||
lastname: form.getValues("lastname"),
|
lastname: form.getValues("lastname"),
|
||||||
@@ -116,13 +116,13 @@ export const Register = () => {
|
|||||||
Login
|
Login
|
||||||
</Link>
|
</Link>
|
||||||
</span>
|
</span>
|
||||||
<div className="alert alert-info alert-outline text-sm font-semibold text-center justify-center">
|
<div className="alert alert-info alert-outline justify-center text-center text-sm font-semibold">
|
||||||
Du warst bereits Nutzer der V1? <br />
|
Du warst bereits Nutzer der V1? <br />
|
||||||
Du musst keinen neuen Account erstellen, sondern kannst dich mit deinen alten Zugangsdaten
|
Du musst keinen neuen Account erstellen, sondern kannst dich mit deinen alten Zugangsdaten
|
||||||
anmelden.
|
anmelden.
|
||||||
</div>
|
</div>
|
||||||
<div className="mt-5 mb-2">
|
<div className="mb-2 mt-5">
|
||||||
<label className="input input-bordered flex items-center gap-2 mt-2 w-full">
|
<label className="input input-bordered mt-2 flex w-full items-center gap-2">
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
viewBox="0 0 16 16"
|
viewBox="0 0 16 16"
|
||||||
@@ -143,7 +143,7 @@ export const Register = () => {
|
|||||||
? form.formState.errors.firstname.message
|
? form.formState.errors.firstname.message
|
||||||
: ""}
|
: ""}
|
||||||
</p>
|
</p>
|
||||||
<label className="input input-bordered flex items-center gap-2 mt-2 w-full">
|
<label className="input input-bordered mt-2 flex w-full items-center gap-2">
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
viewBox="0 0 16 16"
|
viewBox="0 0 16 16"
|
||||||
@@ -165,7 +165,7 @@ export const Register = () => {
|
|||||||
: ""}
|
: ""}
|
||||||
</p>
|
</p>
|
||||||
<div className="divider">Account</div>
|
<div className="divider">Account</div>
|
||||||
<label className="input input-bordered flex items-center gap-2 w-full">
|
<label className="input input-bordered flex w-full items-center gap-2">
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
viewBox="0 0 16 16"
|
viewBox="0 0 16 16"
|
||||||
@@ -183,7 +183,7 @@ export const Register = () => {
|
|||||||
? form.formState.errors.email.message
|
? form.formState.errors.email.message
|
||||||
: ""}
|
: ""}
|
||||||
</p>
|
</p>
|
||||||
<label className="input input-bordered flex items-center gap-2 mt-2 w-full">
|
<label className="input input-bordered mt-2 flex w-full items-center gap-2">
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
viewBox="0 0 16 16"
|
viewBox="0 0 16 16"
|
||||||
@@ -209,7 +209,7 @@ export const Register = () => {
|
|||||||
? form.formState.errors.password.message
|
? form.formState.errors.password.message
|
||||||
: ""}
|
: ""}
|
||||||
</p>
|
</p>
|
||||||
<label className="input input-bordered flex items-center gap-2 mt-2 w-full">
|
<label className="input input-bordered mt-2 flex w-full items-center gap-2">
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
viewBox="0 0 16 16"
|
viewBox="0 0 16 16"
|
||||||
|
|||||||
@@ -29,7 +29,9 @@ export const register = async ({ password, ...user }: Omit<Prisma.UserCreateInpu
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const existingOldUser = (OLD_USER as OldUser[]).find((u) => u.email.toLocaleLowerCase() === user.email.toLocaleLowerCase());
|
const existingOldUser = (OLD_USER as OldUser[]).find(
|
||||||
|
(u) => u.email.toLocaleLowerCase() === user.email,
|
||||||
|
);
|
||||||
|
|
||||||
if (existingUser) {
|
if (existingUser) {
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -18,9 +18,16 @@ export const options: AuthOptions = {
|
|||||||
try {
|
try {
|
||||||
if (!credentials) throw new Error("No credentials provided");
|
if (!credentials) throw new Error("No credentials provided");
|
||||||
const user = await prisma.user.findFirst({
|
const user = await prisma.user.findFirst({
|
||||||
where: { email: credentials.email },
|
where: {
|
||||||
|
email: {
|
||||||
|
contains: credentials.email,
|
||||||
|
mode: "insensitive",
|
||||||
|
},
|
||||||
|
},
|
||||||
});
|
});
|
||||||
const v1User = (oldUser as OldUser[]).find((u) => u.email.toLowerCase() === credentials.email.toLowerCase());
|
const v1User = (oldUser as OldUser[]).find(
|
||||||
|
(u) => u.email.toLowerCase() === credentials.email,
|
||||||
|
);
|
||||||
if (!user && v1User) {
|
if (!user && v1User) {
|
||||||
if (bcrypt.compareSync(credentials.password, v1User.password)) {
|
if (bcrypt.compareSync(credentials.password, v1User.password)) {
|
||||||
const newUser = await createNewUserFromOld(v1User);
|
const newUser = await createNewUserFromOld(v1User);
|
||||||
|
|||||||
@@ -31,6 +31,29 @@ export interface OldUser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const createNewUserFromOld = async (oldUser: OldUser) => {
|
export const createNewUserFromOld = async (oldUser: OldUser) => {
|
||||||
|
const existingPublicId = await prisma.user.findFirst({
|
||||||
|
where: {
|
||||||
|
publicId: oldUser.publicId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
let varPublicId = oldUser.publicId;
|
||||||
|
|
||||||
|
if (existingPublicId) {
|
||||||
|
const lastUserPublicId = await prisma.user.findFirst({
|
||||||
|
select: {
|
||||||
|
publicId: true,
|
||||||
|
},
|
||||||
|
orderBy: {
|
||||||
|
publicId: "desc",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
if (lastUserPublicId) {
|
||||||
|
const lastUserInt = parseInt(lastUserPublicId.publicId.replace("VAR", ""));
|
||||||
|
varPublicId = `VAR${(lastUserInt + 1).toString().padStart(4, "0")}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const newUser = await prisma.user.create({
|
const newUser = await prisma.user.create({
|
||||||
data: {
|
data: {
|
||||||
email: oldUser.email,
|
email: oldUser.email,
|
||||||
@@ -38,7 +61,7 @@ export const createNewUserFromOld = async (oldUser: OldUser) => {
|
|||||||
migratedFromV1: true,
|
migratedFromV1: true,
|
||||||
firstname: oldUser.firstname,
|
firstname: oldUser.firstname,
|
||||||
lastname: oldUser.lastname,
|
lastname: oldUser.lastname,
|
||||||
publicId: oldUser.publicId,
|
publicId: varPublicId,
|
||||||
badges: [
|
badges: [
|
||||||
...oldUser.badges
|
...oldUser.badges
|
||||||
.map((badge) => {
|
.map((badge) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user