diff --git a/frontend/src/routes/auth/admin/users/+page.server.js b/frontend/src/routes/auth/admin/users/+page.server.js index 15d06b1..5fd1ab6 100644 --- a/frontend/src/routes/auth/admin/users/+page.server.js +++ b/frontend/src/routes/auth/admin/users/+page.server.js @@ -187,6 +187,37 @@ export const actions = { return fail(400, { errors: errors }); } + const response = await res.json(); + console.log('Server success response:', response); + throw redirect(303, `${base}/auth/admin/users`); + }, + grantBackendAccess: async ({ request, fetch, cookies }) => { + let formData = await request.formData(); + + const rawData = formDataToObject(formData); + const processedData = processUserFormData(rawData); + console.dir(processedData); + const apiURL = `${BASE_API_URI}/auth/users/activate`; + + /** @type {RequestInit} */ + const requestOptions = { + method: 'PATCH', + credentials: 'include', + headers: { + 'Content-Type': 'application/json', + Cookie: `jwt=${cookies.get('jwt')}` + }, + body: JSON.stringify(processedData) + }; + + const res = await fetch(apiURL, requestOptions); + + if (!res.ok) { + const response = await res.json(); + const errors = formatError(response.errors); + return fail(400, { errors: errors }); + } + const response = await res.json(); console.log('Server success response:', response); throw redirect(303, `${base}/auth/admin/users`); diff --git a/frontend/src/routes/auth/admin/users/+page.svelte b/frontend/src/routes/auth/admin/users/+page.svelte index 65f3da7..a2b85e8 100644 --- a/frontend/src/routes/auth/admin/users/+page.svelte +++ b/frontend/src/routes/auth/admin/users/+page.svelte @@ -234,6 +234,41 @@ {$t('user.id')} {user.id} + + +
{ + return async ({ result }) => { + if (result.type === 'success' || result.type === 'redirect') { + await applyAction(result); + } + }; + }} + on:submit|preventDefault={(/** @type {SubmitEvent} */ e) => { + if ( + !confirm( + $t('dialog.backend_access', { + values: { + firstname: user.first_name || '', + lastname: user.last_name || '' + } + }) + ) + ) { + e.preventDefault(); // Cancel form submission if user declines + } + }} + > + + +
+ + {$t('name')} {user.first_name} {user.last_name} @@ -568,6 +603,7 @@ display: flex; align-items: center; gap: 1rem; + flex-wrap: wrap; /* Allows wrapping on small screens */ margin-bottom: 1rem; } .container { diff --git a/go-backend/internal/constants/constants.go b/go-backend/internal/constants/constants.go index b761977..5ed923e 100644 --- a/go-backend/internal/constants/constants.go +++ b/go-backend/internal/constants/constants.go @@ -11,6 +11,7 @@ const ( AwaitingPaymentStatus MailVerificationSubject = "Nur noch ein kleiner Schritt!" MailChangePasswordSubject = "Passwort Änderung angefordert" + MailGrantBackendAccessSubject = "Dein Dörpsmobil Hasloh e.V. Zugang" MailRegistrationSubject = "Neues Mitglied hat sich registriert" MailWelcomeSubject = "Willkommen beim Dörpsmobil Hasloh e.V." MailContactSubject = "Jemand hat das Kontaktformular gefunden" @@ -62,15 +63,17 @@ var VerificationTypes = struct { } var Priviliges = struct { - View int8 - Create int8 - Update int8 - Delete int8 + View int8 + Create int8 + Update int8 + Delete int8 + AccessControl int8 }{ - View: 2, - Update: 4, - Create: 4, - Delete: 4, + View: 2, + Update: 4, + Create: 4, + Delete: 4, + AccessControl: 8, } var Roles = struct { diff --git a/go-backend/internal/controllers/user_Password.go b/go-backend/internal/controllers/user_Password.go index c3468a8..9a6dc30 100644 --- a/go-backend/internal/controllers/user_Password.go +++ b/go-backend/internal/controllers/user_Password.go @@ -4,6 +4,7 @@ import ( "GoMembership/internal/constants" "GoMembership/internal/utils" "GoMembership/pkg/errors" + "fmt" "net/http" "strconv" @@ -12,6 +13,55 @@ import ( "github.com/go-playground/validator/v10" ) +func (uc *UserController) CreatePasswordHandler(c *gin.Context) { + + requestUser, err := uc.ExtractUserFromContext(c) + if err != nil { + utils.RespondWithError(c, err, "Error extracting user from context in UpdateHandler", http.StatusBadRequest, errors.Responses.Fields.User, errors.Responses.Keys.NoAuthToken) + return + } + if !utils.HasPrivilige(requestUser, constants.Priviliges.AccessControl) { + utils.RespondWithError(c, errors.ErrNotAuthorized, fmt.Sprintf("Not allowed to handle all users. RoleID(%v) + + +
+ + + + + + +
+
+ Dörpsmobil Hasloh +
+
+ Moin {{.FirstName}} {{.LastName}} 👋, +
+
+ hiermit erhältst Du Zugnag zu Deinem Dörpsmobil Hasloh Account. +
+
+
+
+
+

+ Mit diesem Link kannst Du Dich dann in Deinen Dörpsmobil Hasloh Account anmelden: +

+

+ + {{.BASEURL}}{{.FRONTEND_PATH}}/ + +

+

+ Dafür musst Du aber zunächst noch Dein Passwort erstellen. +

+
+ +
+ Alternativ kannst Du auch diesen Link in Deinem Browser öffnen: +
+
+ {{.BASEURL}}{{.FRONTEND_PATH}}/auth/password/change/{{.UserID}}?token={{.Token}} +
+
+ Mit Freundlichen Grüßen, +
+
+ Der Vorstand +
+
+ +
+
+
+ + diff --git a/go-backend/templates/email/mail_grant_backend_access.txt.tmpl b/go-backend/templates/email/mail_grant_backend_access.txt.tmpl new file mode 100644 index 0000000..4f07f76 --- /dev/null +++ b/go-backend/templates/email/mail_grant_backend_access.txt.tmpl @@ -0,0 +1,17 @@ +Moin {{.FirstName}} {{.LastName}} 👋, + +hiermit erhältst Du Zugnag zu Deinem Dörpsmobil Hasloh Account. + +Mit diesem Link kannst Du Dich dann in Deinen Dörpsmobil Hasloh Account anmelden: + +{{.BASEURL}}{{.FRONTEND_PATH}}/ + +einloggen. + +Dafür musst Du aber zunächst noch Dein Passwort erstellen: + +{{.BASEURL}}{{.FRONTEND_PATH}}/auth/password/change/{{.UserID}}?token={{.Token}} + +Mit Freundlichen Grüßen, + +Der Vorstand