feat(frontend): list tokens, use formatted dates
This commit is contained in:
		
							parent
							
								
									4fbbafc763
								
							
						
					
					
						commit
						bfa810fbb2
					
				
					 10 changed files with 66 additions and 18 deletions
				
			
		|  | @ -43,6 +43,7 @@ | |||
| 		"base64-arraybuffer": "^1.0.2", | ||||
| 		"bootstrap": "5.3.0-alpha1", | ||||
| 		"bootstrap-icons": "^1.10.3", | ||||
| 		"jose": "^4.13.1", | ||||
| 		"luxon": "^3.3.0", | ||||
| 		"marked": "^4.2.12", | ||||
| 		"sanitize-html": "^2.10.0", | ||||
|  |  | |||
							
								
								
									
										6
									
								
								frontend/pnpm-lock.yaml
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										6
									
								
								frontend/pnpm-lock.yaml
									
										
									
										generated
									
									
									
								
							|  | @ -20,6 +20,7 @@ specifiers: | |||
|   eslint: ^8.28.0 | ||||
|   eslint-config-prettier: ^8.5.0 | ||||
|   eslint-plugin-svelte3: ^4.0.0 | ||||
|   jose: ^4.13.1 | ||||
|   luxon: ^3.3.0 | ||||
|   marked: ^4.2.12 | ||||
|   postcss: ^8.4.21 | ||||
|  | @ -40,6 +41,7 @@ dependencies: | |||
|   base64-arraybuffer: 1.0.2 | ||||
|   bootstrap: 5.3.0-alpha1_@popperjs+core@2.11.6 | ||||
|   bootstrap-icons: 1.10.3 | ||||
|   jose: 4.13.1 | ||||
|   luxon: 3.3.0 | ||||
|   marked: 4.2.12 | ||||
|   sanitize-html: 2.10.0 | ||||
|  | @ -1546,6 +1548,10 @@ packages: | |||
|     resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} | ||||
|     dev: true | ||||
| 
 | ||||
|   /jose/4.13.1: | ||||
|     resolution: {integrity: sha512-MSJQC5vXco5Br38mzaQKiq9mwt7lwj2eXpgpRyQYNHYt2lq1PjkWa7DLXX0WVcQLE9HhMh3jPiufS7fhJf+CLQ==} | ||||
|     dev: false | ||||
| 
 | ||||
|   /js-sdsl/4.3.0: | ||||
|     resolution: {integrity: sha512-mifzlm2+5nZ+lEcLJMoBK0/IH/bDg8XnJfd/Wq6IP+xoCjLZsTOnV2QpxlVbX9bMnkl5PdEjNtBJ9Cj1NjifhQ==} | ||||
|     dev: true | ||||
|  |  | |||
|  | @ -74,7 +74,7 @@ export interface MemberPartialUser { | |||
| 
 | ||||
| export interface Invite { | ||||
|   code: string; | ||||
|   created: Date; | ||||
|   created: string; | ||||
|   used: boolean; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -32,5 +32,5 @@ interface CallbackResponse { | |||
|   require_invite: boolean; | ||||
| 
 | ||||
|   is_deleted: boolean; | ||||
|   deleted_at?: Date; | ||||
|   deleted_at?: string; | ||||
| } | ||||
|  |  | |||
|  | @ -46,7 +46,7 @@ | |||
|           active={$page.url.pathname === "/settings/tokens"} | ||||
|           href="/settings/tokens" | ||||
|         > | ||||
|           API tokens | ||||
|           Tokens | ||||
|         </ListGroupItem> | ||||
|         <ListGroupItem | ||||
|           tag="a" | ||||
|  |  | |||
|  | @ -5,16 +5,7 @@ | |||
|   import ErrorAlert from "$lib/components/ErrorAlert.svelte"; | ||||
|   import FallbackImage from "$lib/components/FallbackImage.svelte"; | ||||
|   import { userStore } from "$lib/store"; | ||||
|   import { | ||||
|     Alert, | ||||
|     Button, | ||||
|     Icon, | ||||
|     Modal, | ||||
|     ModalBody, | ||||
|     ModalFooter, | ||||
|     ModalHeader, | ||||
|     Table, | ||||
|   } from "sveltestrap"; | ||||
|   import { Button, Icon, Modal, ModalBody, ModalFooter, ModalHeader, Table } from "sveltestrap"; | ||||
|   import type { PageData } from "./$types"; | ||||
| 
 | ||||
|   export let data: PageData; | ||||
|  |  | |||
|  | @ -15,5 +15,5 @@ export const load = async () => { | |||
| 
 | ||||
| interface ExportResponse { | ||||
|   path: string; | ||||
|   created_at: Date; | ||||
|   created_at: string; | ||||
| } | ||||
|  |  | |||
|  | @ -2,7 +2,8 @@ | |||
|   import type { APIError, Invite } from "$lib/api/entities"; | ||||
|   import { apiFetchClient } from "$lib/api/fetch"; | ||||
|   import ErrorAlert from "$lib/components/ErrorAlert.svelte"; | ||||
|   import { Alert, Button, Modal, Table } from "sveltestrap"; | ||||
|   import { DateTime } from "luxon"; | ||||
|   import { Button, Modal, Table } from "sveltestrap"; | ||||
|   import type { PageData } from "./$types"; | ||||
| 
 | ||||
|   export let data: PageData; | ||||
|  | @ -43,7 +44,11 @@ | |||
|         {#each data.invites as invite} | ||||
|           <tr> | ||||
|             <td><code>{invite.code}</code></td> | ||||
|             <td>{invite.created}</td> | ||||
|             <td | ||||
|               >{DateTime.fromISO(invite.created) | ||||
|                 .toLocal() | ||||
|                 .toLocaleString(DateTime.DATETIME_MED)}</td | ||||
|             > | ||||
|             <td>{invite.used ? "yes" : "no"}</td> | ||||
|           </tr> | ||||
|         {/each} | ||||
|  |  | |||
|  | @ -1,3 +1,36 @@ | |||
| <h1>API tokens</h1> | ||||
| <script lang="ts"> | ||||
|   import { DateTime } from "luxon"; | ||||
|   import { Icon, Table } from "sveltestrap"; | ||||
|   import type { PageData } from "./$types"; | ||||
| 
 | ||||
| <p>This page is a work in progress, sorry!</p> | ||||
|   export let data: PageData; | ||||
| 
 | ||||
|   import * as jose from "jose"; | ||||
|   const claims = jose.decodeJwt(localStorage.getItem("pronouns-token")!); | ||||
| </script> | ||||
| 
 | ||||
| <h1>Tokens ({data.tokens.length})</h1> | ||||
| 
 | ||||
| <Table bordered striped hover> | ||||
|   <thead> | ||||
|     <th>ID</th> | ||||
|     <th>Created at</th> | ||||
|     <th>Expires at</th> | ||||
|     <th>Current?</th> | ||||
|   </thead> | ||||
|   <tbody> | ||||
|     {#each data.tokens as token} | ||||
|       <tr> | ||||
|         <td><code>{token.id}</code></td> | ||||
|         <td>{DateTime.fromISO(token.created).toLocal().toLocaleString(DateTime.DATETIME_MED)}</td> | ||||
|         <td>{DateTime.fromISO(token.expires).toLocal().toLocaleString(DateTime.DATETIME_MED)}</td> | ||||
|         <td | ||||
|           >{#if claims["jti"] === token.id}<Icon name="check-lg" alt="Current token" />{:else}<Icon | ||||
|               name="x-lg" | ||||
|               alt="Not current token" | ||||
|             />{/if}</td | ||||
|         > | ||||
|       </tr> | ||||
|     {/each} | ||||
|   </tbody> | ||||
| </Table> | ||||
|  |  | |||
							
								
								
									
										12
									
								
								frontend/src/routes/settings/tokens/+page.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								frontend/src/routes/settings/tokens/+page.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,12 @@ | |||
| import { apiFetchClient } from "$lib/api/fetch"; | ||||
| 
 | ||||
| export const load = async () => { | ||||
|   const tokens = await apiFetchClient<Token[]>("/auth/tokens"); | ||||
|   return { tokens }; | ||||
| }; | ||||
| 
 | ||||
| interface Token { | ||||
|   id: string; | ||||
|   created: string; | ||||
|   expires: string; | ||||
| } | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue