Skip to content

Commit 84fce00

Browse files
committed
enforce display name lock
1 parent c88352a commit 84fce00

3 files changed

Lines changed: 73 additions & 35 deletions

File tree

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,8 @@ import (
1010
"strings"
1111
)
1212

13-
func validateUser(user *database.DBUser, response *models.FormResponse) {
14-
// Title is required
15-
if strings.Trim(user.DisplayName, " ") == "" {
13+
func validateDisplayName(displayName string, response *models.FormResponse) {
14+
if displayName == "" {
1615
response.AddError("DisplayName", "required")
1716
}
1817
}
@@ -33,28 +32,47 @@ func (server *Server) GetUser(ctx *gin.Context) {
3332
ctx.Status(http.StatusUnauthorized)
3433
}
3534

36-
func (server *Server) PutUser(ctx *gin.Context) {
35+
type PutProfileRequest struct {
36+
DisplayName string
37+
}
38+
39+
func (server *Server) PutProfile(ctx *gin.Context) {
3740
session := sessions.Default(ctx)
3841
userId := session.Get("userId")
3942
if userId != nil {
40-
var user database.DBUser
41-
err := ctx.ShouldBindJSON(&user)
43+
user, err := database.GetUser(convert.StringToUUID(userId.(string)))
44+
if err != nil {
45+
logger.Error("PutProfile: GetUser error: %v", err)
46+
ctx.Status(http.StatusInternalServerError)
47+
return
48+
}
49+
50+
// admin display name lock prevents a user from changing it
51+
if user.LockDisplayName {
52+
logger.Info("DisplayName Locked")
53+
ctx.Status(http.StatusForbidden)
54+
return
55+
}
56+
57+
var request PutProfileRequest
58+
err = ctx.ShouldBindJSON(&request)
4259
if err != nil {
4360
ctx.Status(http.StatusBadRequest)
4461
return
4562
}
4663

4764
response := models.NewFormResponse()
65+
request.DisplayName = strings.Trim(request.DisplayName, " ")
4866

4967
// Perform validation
50-
validateUser(&user, &response)
68+
validateDisplayName(request.DisplayName, &response)
5169
if len(response.Errors) > 0 {
5270
logger.Error("Validation Error: %v+", user)
5371
ctx.JSON(http.StatusBadRequest, response)
5472
return
5573
}
5674

57-
user.Id = convert.StringToUUID(userId.(string))
75+
user.DisplayName = request.DisplayName
5876
_, err = database.UpdateUser(user)
5977
if err != nil {
6078
logger.Error("Error calling database.UpdateEvent: %v", err)
@@ -92,7 +110,7 @@ func (server *Server) SetupUserRoutes() {
92110
group := server.Gin.Group("/user")
93111
{
94112
group.GET("/", server.GetUser)
95-
group.PUT("/", server.PutUser)
113+
group.PUT("/profile", server.PutProfile)
96114
group.GET("/logout", server.Logout)
97115
}
98116

html/src/lib/pages/ProfilePage.svelte

Lines changed: 33 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
<script lang="ts">
22
33
import Page from "../components/Page.svelte";
4-
import {Button, Card, Input, Spinner} from "flowbite-svelte";
4+
import {Button, Card, Input, Spinner, Tooltip} from "flowbite-svelte";
55
import FormField from "../components/FormField.svelte";
66
import Form from "../components/Form.svelte";
77
import type {ActiveUser, User} from "../models/user";
88
import {putProfile} from "../services/services";
99
import {activeUserStore} from "../stores/stores";
10+
import {FontAwesomeIcon} from "@fortawesome/svelte-fontawesome";
11+
import {faLock} from "@fortawesome/free-solid-svg-icons";
1012
1113
let isSaving : boolean = false;
1214
let formData: User | null = null;
@@ -24,7 +26,7 @@
2426
isSaving = true;
2527
clearErrors();
2628
try {
27-
const response = await putProfile(formData);
29+
const response = await putProfile(formData.DisplayName);
2830
parseResponse(response);
2931
const responseData = await response.json();
3032
activeUserStore.set(<ActiveUser>{user: <User>responseData.Data, loggedIn: true});
@@ -41,27 +43,38 @@
4143

4244
<Page>
4345

44-
<Card size="xl" class="w-full">
46+
<Card size="lg" class="w-full">
4547
<h2>Edit Profile</h2>
46-
{#if formData !== null}
47-
<div class="flex flex-col gap-8 my-8">
48-
<Form bind:clearErrors bind:parseResponse>
49-
<FormField label="Display Name" name="DisplayName">
50-
<Input bind:value={formData.DisplayName}></Input>
51-
</FormField>
52-
</Form>
53-
</div>
48+
{#await $activeUserStore}
49+
{:then activeUser}
50+
{#if formData !== null}
51+
{#if activeUser !== null}
52+
<div class="flex flex-col gap-8 my-8">
53+
<Form bind:clearErrors bind:parseResponse>
54+
{#if activeUser.user?.LockDisplayName}
55+
<div class="font-bold">
56+
Display Name <FontAwesomeIcon icon={faLock}/>
57+
<Tooltip>Your Display Name has been locked by an admin and may not be changed</Tooltip>
58+
</div>
59+
<div>{formData.DisplayName}</div>
60+
{:else}
61+
<FormField label="Display Name" name="DisplayName">
62+
<Input bind:value={formData.DisplayName}></Input>
63+
</FormField>
64+
{/if}
65+
</Form>
66+
</div>
5467

55-
<Button on:click={saveForm} disabled={isSaving}>
56-
{#if isSaving}
57-
<Spinner />
58-
{:else}
59-
Save
68+
<Button on:click={saveForm} disabled={isSaving || activeUser.user?.LockDisplayName}>
69+
{#if isSaving}
70+
<Spinner />
71+
{:else}
72+
Save
73+
{/if}
74+
</Button>
6075
{/if}
61-
</Button>
62-
{:else}
63-
<Spinner />
64-
{/if}
76+
{/if}
77+
{/await}
6578
</Card>
6679

6780

html/src/lib/services/services.ts

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,19 @@ export async function getUser() {
4646
});
4747
}
4848

49-
export async function putProfile(user: User): Promise<Response> {
50-
return fetch(baseApiUrl + "/user/",
51-
{
52-
method: "PUT",
53-
body: JSON.stringify(user)
54-
});
49+
interface PutProfileRequest {
50+
DisplayName : string,
51+
}
52+
export async function putProfile(displayName: string): Promise<Response> {
53+
const requestInit : RequestInit = {
54+
method: 'PUT',
55+
body: JSON.stringify(
56+
<PutProfileRequest>{
57+
DisplayName: displayName
58+
}
59+
)
60+
}
61+
return await fetch(`${baseApiUrl}/user/profile/`, requestInit);
5562
}
5663

5764
export async function logout() {

0 commit comments

Comments
 (0)