From a3aed11654184b9be57b8966a7882dc7e5cc1d69 Mon Sep 17 00:00:00 2001 From: Robin Munn Date: Thu, 18 Apr 2024 15:40:26 +0700 Subject: [PATCH 01/42] Add "Create User" button to admin dashboard Doesn't do anything... yet. --- frontend/src/lib/i18n/locales/en.json | 1 + .../routes/(authenticated)/admin/+page.svelte | 26 +++++++++++++------ 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/frontend/src/lib/i18n/locales/en.json b/frontend/src/lib/i18n/locales/en.json index 25e5d57f0..db5cd9ee7 100644 --- a/frontend/src/lib/i18n/locales/en.json +++ b/frontend/src/lib/i18n/locales/en.json @@ -13,6 +13,7 @@ "column_edit": "Edit", "project_table_title": "Projects", "user_table_title": "Users", + "create_user": "Create User", "is_draft": "Draft", "email_not_verified": "Not Verified", "notifications": { diff --git a/frontend/src/routes/(authenticated)/admin/+page.svelte b/frontend/src/routes/(authenticated)/admin/+page.svelte index 553f4beeb..da56c4fb4 100644 --- a/frontend/src/routes/(authenticated)/admin/+page.svelte +++ b/frontend/src/routes/(authenticated)/admin/+page.svelte @@ -104,14 +104,24 @@
$queryParamValues.tab = event.detail}> - {$t('admin_dashboard.user_table_title')} - - - {$number(shownUsers.length)} - / - {$number(filteredUserCount)} - - +
+
+ {$t('admin_dashboard.user_table_title')} + + + {$number(shownUsers.length)} + / + {$number(filteredUserCount)} + + +
+ +
Date: Thu, 18 Apr 2024 15:49:49 +0700 Subject: [PATCH 02/42] Extract register page into component --- .../lib/components/Users/CreateUser.svelte | 81 +++++++++++++++++++ .../(unauthenticated)/register/+page.svelte | 80 +----------------- 2 files changed, 83 insertions(+), 78 deletions(-) create mode 100644 frontend/src/lib/components/Users/CreateUser.svelte diff --git a/frontend/src/lib/components/Users/CreateUser.svelte b/frontend/src/lib/components/Users/CreateUser.svelte new file mode 100644 index 000000000..2bf8bb643 --- /dev/null +++ b/frontend/src/lib/components/Users/CreateUser.svelte @@ -0,0 +1,81 @@ + + + + + + + + + + + {$t('register.button_register')} + + diff --git a/frontend/src/routes/(unauthenticated)/register/+page.svelte b/frontend/src/routes/(unauthenticated)/register/+page.svelte index 2bf8bb643..3a59aca66 100644 --- a/frontend/src/routes/(unauthenticated)/register/+page.svelte +++ b/frontend/src/routes/(unauthenticated)/register/+page.svelte @@ -1,81 +1,5 @@ - - - - - - - - - {$t('register.button_register')} - - + From 02bc9e3b603ad56b5790c7c2b1a54a054b7fc092 Mon Sep 17 00:00:00 2001 From: Robin Munn Date: Thu, 18 Apr 2024 16:03:01 +0700 Subject: [PATCH 03/42] Use register page in create-user modal for admins Currently the "sign out and sign back in" behavior of the register page still works as it used to, which is not what we want when an admin is creating the user. We'll change that next. --- .../lib/components/Users/CreateUserModal.svelte | 14 ++++++++++++++ frontend/src/lib/i18n/locales/en.json | 4 +++- .../src/routes/(authenticated)/admin/+page.svelte | 8 ++++++-- 3 files changed, 23 insertions(+), 3 deletions(-) create mode 100644 frontend/src/lib/components/Users/CreateUserModal.svelte diff --git a/frontend/src/lib/components/Users/CreateUserModal.svelte b/frontend/src/lib/components/Users/CreateUserModal.svelte new file mode 100644 index 000000000..a9b97737b --- /dev/null +++ b/frontend/src/lib/components/Users/CreateUserModal.svelte @@ -0,0 +1,14 @@ + + + + + diff --git a/frontend/src/lib/i18n/locales/en.json b/frontend/src/lib/i18n/locales/en.json index db5cd9ee7..ccccfa6db 100644 --- a/frontend/src/lib/i18n/locales/en.json +++ b/frontend/src/lib/i18n/locales/en.json @@ -13,7 +13,6 @@ "column_edit": "Edit", "project_table_title": "Projects", "user_table_title": "Users", - "create_user": "Create User", "is_draft": "Draft", "email_not_verified": "Not Verified", "notifications": { @@ -39,6 +38,9 @@ } } }, + "create_user_modal": { + "create_user": "Create User", + }, "user_details_modal": { "registered": "Registered", "locked": "Locked", diff --git a/frontend/src/routes/(authenticated)/admin/+page.svelte b/frontend/src/routes/(authenticated)/admin/+page.svelte index da56c4fb4..a93f5435a 100644 --- a/frontend/src/routes/(authenticated)/admin/+page.svelte +++ b/frontend/src/routes/(authenticated)/admin/+page.svelte @@ -21,6 +21,7 @@ import { Button } from '$lib/forms'; import { PageBreadcrumb } from '$lib/layout'; import AdminTabs, { type AdminTabId } from './AdminTabs.svelte'; + import CreateUserModal from '$lib/components/Users/CreateUserModal.svelte'; export let data: PageData; $: projects = data.projects; @@ -62,6 +63,7 @@ } let userModal: UserModal; + let createUserModal: CreateUserModal; let deleteUserModal: DeleteUserModal; let formModal: EditUserAccount; @@ -115,9 +117,10 @@
- @@ -234,4 +237,5 @@ + From 8536fd2db3196e29d9eef2c6d8769a91ec4e735c Mon Sep 17 00:00:00 2001 From: Robin Munn Date: Thu, 18 Apr 2024 16:12:21 +0700 Subject: [PATCH 04/42] Don't auto-login user if created by admin --- backend/LexBoxApi/Controllers/UserController.cs | 7 +++++-- backend/LexBoxApi/Models/RegisterAccountInput.cs | 3 ++- frontend/src/lib/components/Users/CreateUser.svelte | 6 ++++-- frontend/src/lib/components/Users/CreateUserModal.svelte | 2 +- frontend/src/lib/user.ts | 3 ++- 5 files changed, 14 insertions(+), 7 deletions(-) diff --git a/backend/LexBoxApi/Controllers/UserController.cs b/backend/LexBoxApi/Controllers/UserController.cs index 01fc14a95..aa480feef 100644 --- a/backend/LexBoxApi/Controllers/UserController.cs +++ b/backend/LexBoxApi/Controllers/UserController.cs @@ -92,8 +92,11 @@ public async Task> RegisterAccount(RegisterAccountInpu await _lexBoxDbContext.SaveChangesAsync(); var user = new LexAuthUser(userEntity); - await HttpContext.SignInAsync(user.GetPrincipal("Registration"), - new AuthenticationProperties { IsPersistent = true }); + if (accountInput.AutoLogin) + { + await HttpContext.SignInAsync(user.GetPrincipal("Registration"), + new AuthenticationProperties { IsPersistent = true }); + } if (!emailVerified) await _emailService.SendVerifyAddressEmail(userEntity); return Ok(user); diff --git a/backend/LexBoxApi/Models/RegisterAccountInput.cs b/backend/LexBoxApi/Models/RegisterAccountInput.cs index b29304da7..ddf3b1576 100644 --- a/backend/LexBoxApi/Models/RegisterAccountInput.cs +++ b/backend/LexBoxApi/Models/RegisterAccountInput.cs @@ -7,4 +7,5 @@ public record RegisterAccountInput([Required(AllowEmptyStrings = false)] string [Required(AllowEmptyStrings = false)] string Locale, [Required(AllowEmptyStrings = false)] string PasswordHash, int? PasswordStrength, - string TurnstileToken); + string TurnstileToken, + bool AutoLogin = true); diff --git a/frontend/src/lib/components/Users/CreateUser.svelte b/frontend/src/lib/components/Users/CreateUser.svelte index 2bf8bb643..77e1477ce 100644 --- a/frontend/src/lib/components/Users/CreateUser.svelte +++ b/frontend/src/lib/components/Users/CreateUser.svelte @@ -9,6 +9,8 @@ import { onMount } from 'svelte'; import { z } from 'zod'; + export let autoLogin = true; + type RegisterPageQueryParams = { name: string; email: string; @@ -26,7 +28,7 @@ }); let { form, errors, message, enhance, submitting } = lexSuperForm(formSchema, async () => { - const { user, error } = await register($form.password, $form.score, $form.name, $form.email, $form.locale, turnstileToken); + const { user, error } = await register($form.password, $form.score, $form.name, $form.email, $form.locale, turnstileToken, autoLogin); if (error) { if (error.turnstile) { $message = $t('turnstile.invalid'); @@ -37,7 +39,7 @@ return; } if (user) { - await goto('/home', { invalidateAll: true }); // invalidate so we get the user from the server + if (autoLogin) await goto('/home', { invalidateAll: true }); // invalidate so we get the user from the server return; } throw new Error('Unknown error, no error from server, but also no user.'); diff --git a/frontend/src/lib/components/Users/CreateUserModal.svelte b/frontend/src/lib/components/Users/CreateUserModal.svelte index a9b97737b..edc45bdf9 100644 --- a/frontend/src/lib/components/Users/CreateUserModal.svelte +++ b/frontend/src/lib/components/Users/CreateUserModal.svelte @@ -10,5 +10,5 @@ - + diff --git a/frontend/src/lib/user.ts b/frontend/src/lib/user.ts index fdd9bcedc..fe3868839 100644 --- a/frontend/src/lib/user.ts +++ b/frontend/src/lib/user.ts @@ -87,7 +87,7 @@ export async function login(userId: string, password: string): Promise { +export async function register(password: string, passwordStrength: number, name: string, email: string, locale: string, turnstileToken: string, autoLogin: boolean): Promise { const response = await fetch('/api/User/registerAccount', { method: 'post', headers: { @@ -99,6 +99,7 @@ export async function register(password: string, passwordStrength: number, name: locale, turnstileToken, passwordStrength, + autoLogin, passwordHash: await hash(password), }) }); From 5d72b13998ea43136470c27b8f5dc4ee889b293d Mon Sep 17 00:00:00 2001 From: Robin Munn Date: Thu, 18 Apr 2024 16:22:01 +0700 Subject: [PATCH 05/42] Hide create-user modal when submit button clicked --- frontend/src/lib/components/Users/CreateUser.svelte | 2 ++ frontend/src/lib/components/Users/CreateUserModal.svelte | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/frontend/src/lib/components/Users/CreateUser.svelte b/frontend/src/lib/components/Users/CreateUser.svelte index 77e1477ce..35e485305 100644 --- a/frontend/src/lib/components/Users/CreateUser.svelte +++ b/frontend/src/lib/components/Users/CreateUser.svelte @@ -10,6 +10,7 @@ import { z } from 'zod'; export let autoLogin = true; + export let onSubmit: (() => void) | undefined = undefined; type RegisterPageQueryParams = { name: string; @@ -39,6 +40,7 @@ return; } if (user) { + if (onSubmit) onSubmit(); if (autoLogin) await goto('/home', { invalidateAll: true }); // invalidate so we get the user from the server return; } diff --git a/frontend/src/lib/components/Users/CreateUserModal.svelte b/frontend/src/lib/components/Users/CreateUserModal.svelte index edc45bdf9..ea70cb344 100644 --- a/frontend/src/lib/components/Users/CreateUserModal.svelte +++ b/frontend/src/lib/components/Users/CreateUserModal.svelte @@ -10,5 +10,5 @@ - + createUserModal.submitModal()} /> From cc8668023c8f2f2497739982458b53d97cfd9aab Mon Sep 17 00:00:00 2001 From: Robin Munn Date: Mon, 13 May 2024 11:50:32 +0700 Subject: [PATCH 06/42] Add helpful tips to top of create-user modal --- .../src/lib/components/Users/CreateUserModal.svelte | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/frontend/src/lib/components/Users/CreateUserModal.svelte b/frontend/src/lib/components/Users/CreateUserModal.svelte index ea70cb344..1e86858e9 100644 --- a/frontend/src/lib/components/Users/CreateUserModal.svelte +++ b/frontend/src/lib/components/Users/CreateUserModal.svelte @@ -1,5 +1,7 @@  + +

+ Did you know you can also create users on a project page? That also allows you to make those users members of the project in one step; + users created here will not be members of any project and will need a second step to add them to a project. +

+

+ If you want to create multiple users at once, the best way is probably to use the Bulk Add/Create Project Members tool. +

createUserModal.submitModal()} />
From 2606313e0956bd055bef89808370fc4d68082c7e Mon Sep 17 00:00:00 2001 From: Robin Munn Date: Mon, 13 May 2024 11:58:57 +0700 Subject: [PATCH 07/42] Don't change browser title in modal When clicking on "Create User" in admin dashboard, we don't want the modal to change the browser title; that should be reserved for the dedicated Register page. --- frontend/src/lib/components/Users/CreateUser.svelte | 3 --- frontend/src/routes/(unauthenticated)/register/+page.svelte | 6 +++++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/frontend/src/lib/components/Users/CreateUser.svelte b/frontend/src/lib/components/Users/CreateUser.svelte index c140f37fd..497561668 100644 --- a/frontend/src/lib/components/Users/CreateUser.svelte +++ b/frontend/src/lib/components/Users/CreateUser.svelte @@ -3,7 +3,6 @@ import PasswordStrengthMeter from '$lib/components/PasswordStrengthMeter.svelte'; import { SubmitButton, FormError, Input, ProtectedForm, lexSuperForm, passwordFormRules, DisplayLanguageSelect } from '$lib/forms'; import t, { getLanguageCodeFromNavigator, locale } from '$lib/i18n'; - import { TitlePage } from '$lib/layout'; import { register } from '$lib/user'; import { getSearchParamValues } from '$lib/util/query-params'; import { onMount } from 'svelte'; @@ -56,7 +55,6 @@ }); -