Monorepo for Tangled tangled.org

appview/settings: add account management UI for tngl.sh users #1151

merged opened by oyster.cafe targeting master from appview-acc-mgmt-ui

tngl.sh users should be able to:

  • change handle
  • deactivate account
  • delete account
  • change password
Labels

None yet.

assignee

None yet.

Participants 2
AT URI
at://did:plc:3fwecdnvtcscjnrx2p4n7alz/sh.tangled.repo.pull/3mgu4bwsml322
+60 -59
Interdiff #2 โ†’ #3
appview/config/config.go

This file has not been changed.

appview/oauth/handler.go

This file has not been changed.

appview/oauth/oauth.go

This file has not been changed.

+3 -57
appview/pages/htmx.go
··· 26 } 27 28 func (s *Pages) DangerPasswordTokenStep(w http.ResponseWriter) { 29 - html := `<div id="password-form-container" hx-swap-oob="innerHTML"> 30 - <label class="uppercase text-sm font-bold p-0">Change password</label> 31 - <p class="text-sm text-gray-500 dark:text-gray-400 pt-1">Check your email for a password reset code.</p> 32 - <form hx-post="/settings/password/reset" hx-swap="none" hx-disabled-elt="find button[type='submit']" class="flex flex-col gap-3 pt-2"> 33 - <div class="flex flex-col"> 34 - <label for="token">reset code</label> 35 - <input type="text" id="token" name="token" required autocomplete="off" placeholder="xxxx-xxxx" /> 36 - </div> 37 - <div class="flex flex-col"> 38 - <label for="new-password">new password</label> 39 - <input type="password" id="new-password" name="new_password" required autocomplete="new-password" /> 40 - </div> 41 - <div class="flex flex-col"> 42 - <label for="confirm-password">confirm new password</label> 43 - <input type="password" id="confirm-password" name="confirm_password" required autocomplete="new-password" /> 44 - </div> 45 - <div class="flex gap-2 pt-2"> 46 - <button type="button" popovertarget="change-password-modal" popovertargetaction="hide" class="btn w-1/2 flex items-center gap-2 text-red-500 hover:text-red-700 dark:text-red-400 dark:hover:text-red-300">cancel</button> 47 - <button type="submit" class="btn w-1/2 flex items-center justify-center gap-2">set new password</button> 48 - </div> 49 - <div id="password-error" class="text-red-500 dark:text-red-400 text-sm empty:hidden"></div> 50 - </form> 51 - </div>` 52 - 53 w.Header().Set("Content-Type", "text/html") 54 w.WriteHeader(http.StatusOK) 55 - w.Write([]byte(html)) 56 } 57 58 func (s *Pages) DangerPasswordSuccess(w http.ResponseWriter) { 59 - html := `<div id="password-form-container" hx-swap-oob="innerHTML"> 60 - <label class="uppercase text-sm font-bold p-0">Change password</label> 61 - <p class="text-green-500 dark:text-green-400 pt-2">Password changed.</p> 62 - </div>` 63 - 64 w.Header().Set("Content-Type", "text/html") 65 w.WriteHeader(http.StatusOK) 66 - w.Write([]byte(html)) 67 } 68 69 func (s *Pages) DangerDeleteTokenStep(w http.ResponseWriter) { 70 - html := `<div id="delete-form-container" hx-swap-oob="innerHTML"> 71 - <label class="uppercase text-sm font-bold p-0 text-red-600 dark:text-red-400">Delete account</label> 72 - <p class="text-sm text-gray-500 dark:text-gray-400 pt-1">Check your email for an account deletion code.</p> 73 - <form hx-post="/settings/delete/confirm" hx-swap="none" hx-confirm="This will permanently delete your account. This cannot be undone. Continue?" hx-disabled-elt="find button[type='submit']" class="flex flex-col gap-3 pt-2"> 74 - <div class="flex flex-col"> 75 - <label for="delete-token">deletion code</label> 76 - <input type="text" id="delete-token" name="token" required autocomplete="off" placeholder="xxxx-xxxx" /> 77 - </div> 78 - <div class="flex flex-col"> 79 - <label for="delete-password-confirm">password</label> 80 - <input type="password" id="delete-password-confirm" name="password" required autocomplete="current-password" /> 81 - </div> 82 - <div class="flex flex-col"> 83 - <label for="delete-confirmation">confirmation</label> 84 - <input type="text" id="delete-confirmation" name="confirmation" required autocomplete="off" placeholder="delete my account" /> 85 - <span class="text-sm text-gray-500 mt-1">Type <strong>delete my account</strong> to confirm.</span> 86 - </div> 87 - <div class="flex gap-2 pt-2"> 88 - <button type="button" popovertarget="delete-modal" popovertargetaction="hide" class="btn w-1/2 flex items-center gap-2 text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-300">cancel</button> 89 - <button type="submit" class="btn w-1/2 flex items-center justify-center gap-2 text-red-600 hover:text-red-700 dark:text-red-400 dark:hover:text-red-300">delete account</button> 90 - </div> 91 - <div id="delete-error" class="text-red-500 dark:text-red-400 text-sm empty:hidden"></div> 92 - </form> 93 - </div>` 94 - 95 w.Header().Set("Content-Type", "text/html") 96 w.WriteHeader(http.StatusOK) 97 - w.Write([]byte(html)) 98 } 99 100 // HxRefresh is a client-side full refresh of the page.
··· 26 } 27 28 func (s *Pages) DangerPasswordTokenStep(w http.ResponseWriter) { 29 w.Header().Set("Content-Type", "text/html") 30 w.WriteHeader(http.StatusOK) 31 + s.executePlain("user/settings/fragments/dangerPasswordToken", w, nil) 32 } 33 34 func (s *Pages) DangerPasswordSuccess(w http.ResponseWriter) { 35 w.Header().Set("Content-Type", "text/html") 36 w.WriteHeader(http.StatusOK) 37 + s.executePlain("user/settings/fragments/dangerPasswordSuccess", w, nil) 38 } 39 40 func (s *Pages) DangerDeleteTokenStep(w http.ResponseWriter) { 41 w.Header().Set("Content-Type", "text/html") 42 w.WriteHeader(http.StatusOK) 43 + s.executePlain("user/settings/fragments/dangerDeleteToken", w, nil) 44 } 45 46 // HxRefresh is a client-side full refresh of the page.
-1
appview/pages/pages.go
··· 441 Claim *models.DomainClaim 442 SitesDomain string 443 IsTnglHandle bool 444 - IsTnglSh bool 445 Tab string 446 } 447
··· 441 Claim *models.DomainClaim 442 SitesDomain string 443 IsTnglHandle bool 444 Tab string 445 } 446
appview/pages/templates/user/settings/profile.html

This file has not been changed.

appview/settings/danger.go

This file has not been changed.

-1
appview/settings/settings.go
··· 119 Claim: claim, 120 SitesDomain: s.Config.Sites.Domain, 121 IsTnglHandle: isTnglHandle, 122 - IsTnglSh: s.isTnglShUser(user.Pds()), 123 }) 124 } 125
··· 119 Claim: claim, 120 SitesDomain: s.Config.Sites.Domain, 121 IsTnglHandle: isTnglHandle, 122 }) 123 } 124
appview/state/login.go

This file has not been changed.

+26
appview/pages/templates/user/settings/fragments/dangerDeleteToken.html
···
··· 1 + {{ define "user/settings/fragments/dangerDeleteToken" }} 2 + <div id="delete-form-container" hx-swap-oob="innerHTML"> 3 + <label class="uppercase text-sm font-bold p-0 text-red-600 dark:text-red-400">Delete account</label> 4 + <p class="text-sm text-gray-500 dark:text-gray-400 pt-1">Check your email for an account deletion code.</p> 5 + <form hx-post="/settings/delete/confirm" hx-swap="none" hx-confirm="This will permanently delete your account. This cannot be undone. Continue?" hx-disabled-elt="find button[type='submit']" class="flex flex-col gap-3 pt-2"> 6 + <div class="flex flex-col"> 7 + <label for="delete-token">deletion code</label> 8 + <input type="text" id="delete-token" name="token" required autocomplete="off" placeholder="xxxx-xxxx" /> 9 + </div> 10 + <div class="flex flex-col"> 11 + <label for="delete-password-confirm">password</label> 12 + <input type="password" id="delete-password-confirm" name="password" required autocomplete="current-password" /> 13 + </div> 14 + <div class="flex flex-col"> 15 + <label for="delete-confirmation">confirmation</label> 16 + <input type="text" id="delete-confirmation" name="confirmation" required autocomplete="off" placeholder="delete my account" /> 17 + <span class="text-sm text-gray-500 mt-1">Type <strong>delete my account</strong> to confirm.</span> 18 + </div> 19 + <div class="flex gap-2 pt-2"> 20 + <button type="button" popovertarget="delete-modal" popovertargetaction="hide" class="btn w-1/2 flex items-center gap-2 text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-300">cancel</button> 21 + <button type="submit" class="btn w-1/2 flex items-center justify-center gap-2 text-red-600 hover:text-red-700 dark:text-red-400 dark:hover:text-red-300">delete account</button> 22 + </div> 23 + <div id="delete-error" class="text-red-500 dark:text-red-400 text-sm empty:hidden"></div> 24 + </form> 25 + </div> 26 + {{ end }}
+6
appview/pages/templates/user/settings/fragments/dangerPasswordSuccess.html
···
··· 1 + {{ define "user/settings/fragments/dangerPasswordSuccess" }} 2 + <div id="password-form-container" hx-swap-oob="innerHTML"> 3 + <label class="uppercase text-sm font-bold p-0">Change password</label> 4 + <p class="text-green-500 dark:text-green-400 pt-2">Password changed.</p> 5 + </div> 6 + {{ end }}
+25
appview/pages/templates/user/settings/fragments/dangerPasswordToken.html
···
··· 1 + {{ define "user/settings/fragments/dangerPasswordToken" }} 2 + <div id="password-form-container" hx-swap-oob="innerHTML"> 3 + <label class="uppercase text-sm font-bold p-0">Change password</label> 4 + <p class="text-sm text-gray-500 dark:text-gray-400 pt-1">Check your email for a password reset code.</p> 5 + <form hx-post="/settings/password/reset" hx-swap="none" hx-disabled-elt="find button[type='submit']" class="flex flex-col gap-3 pt-2"> 6 + <div class="flex flex-col"> 7 + <label for="token">reset code</label> 8 + <input type="text" id="token" name="token" required autocomplete="off" placeholder="xxxx-xxxx" /> 9 + </div> 10 + <div class="flex flex-col"> 11 + <label for="new-password">new password</label> 12 + <input type="password" id="new-password" name="new_password" required autocomplete="new-password" /> 13 + </div> 14 + <div class="flex flex-col"> 15 + <label for="confirm-password">confirm new password</label> 16 + <input type="password" id="confirm-password" name="confirm_password" required autocomplete="new-password" /> 17 + </div> 18 + <div class="flex gap-2 pt-2"> 19 + <button type="button" popovertarget="change-password-modal" popovertargetaction="hide" class="btn w-1/2 flex items-center gap-2 text-red-500 hover:text-red-700 dark:text-red-400 dark:hover:text-red-300">cancel</button> 20 + <button type="submit" class="btn w-1/2 flex items-center justify-center gap-2">set new password</button> 21 + </div> 22 + <div id="password-error" class="text-red-500 dark:text-red-400 text-sm empty:hidden"></div> 23 + </form> 24 + </div> 25 + {{ end }}

History

7 rounds 4 comments
sign up or login to add to the discussion
1 commit
expand
appview/settings: add account management UI for tngl.sh users
3/3 success
expand
expand 0 comments
pull request successfully merged
1 commit
expand
appview/settings: add account management UI for tngl.sh users
3/3 success
expand
expand 0 comments
1 commit
expand
appview/settings: add account management UI for tngl.sh users
3/3 success
expand
expand 1 comment
  • this can go in pages.go
1 commit
expand
appview/settings: add account management UI for tngl.sh users
3/3 success
expand
expand 0 comments
1 commit
expand
appview/settings: add account management UI for tngl.sh users
2/3 failed, 1/3 success
expand
expand 3 comments
  • here could you explain what an elevated auth flow is
  • here why not a template here? does this need to be in htmx.go?
  • here do we need this IsTnglSh bool?
  • here are there any indigo bits to achieve this?
  • here we have defined isTnglShUser once here, and another time here

do we need both?

1 commit
expand
appview/settings: add account management UI for tngl.sh users
3/3 failed
expand
expand 0 comments
1 commit
expand
appview/settings: add account management UI for tngl.sh users
3/3 success
expand
expand 0 comments