diff --git a/web/source/settings/views/user/menu.tsx b/web/source/settings/views/user/menu.tsx index d6a5b9f61..570912ef2 100644 --- a/web/source/settings/views/user/menu.tsx +++ b/web/source/settings/views/user/menu.tsx @@ -64,7 +64,7 @@ export default function UserMenu() { icon="fa-floppy-o" /> diff --git a/web/source/settings/views/user/tokens/index.tsx b/web/source/settings/views/user/tokens/index.tsx index 5882491fe..6569b1c70 100644 --- a/web/source/settings/views/user/tokens/index.tsx +++ b/web/source/settings/views/user/tokens/index.tsx @@ -24,14 +24,22 @@ export default function Tokens() { return (
-

App Tokens

+

Access Tokens

On this page you can search through access tokens owned by applications that you have authorized to access your account and/or perform actions on your behalf.
You can invalidate a token by clicking on the invalidate button under a token. This will remove the token from the database.
The application that was authorized to access your account with that token will then no longer be authorized to do so, and you will need to log out and log in again with that application. -
In cases where you've logged into an application multiple times, or logged in with multiple devices or browsers, you may see multiple tokens for one application. This is normal! +
In cases where you've logged in with an application multiple times, or logged in with multiple devices or browsers, you may see multiple tokens with the same application name. This is normal!
That said, feel free to invalidate old tokens that are never used, it's good security practice and it's fun to click the big red button.

+ + Learn more about access tokens (opens in a new tab) +
diff --git a/web/source/settings/views/user/tokens/search.tsx b/web/source/settings/views/user/tokens/search.tsx index 26f69a2b7..87080cc8f 100644 --- a/web/source/settings/views/user/tokens/search.tsx +++ b/web/source/settings/views/user/tokens/search.tsx @@ -125,8 +125,42 @@ interface TokenInfoListEntryProps { } function TokenInfoListEntry({ tokenInfo }: TokenInfoListEntryProps) { - const created = new Date(tokenInfo.created_at).toLocaleString(); - const lastUsed = tokenInfo.last_used ? new Date(tokenInfo.last_used).toDateString(): "unknown/never"; + const appWebsite = useMemo(() => { + if (!tokenInfo.application.website) { + return ""; + } + + try { + // Try to parse nicely and return link. + const websiteURL = new URL(tokenInfo.application.website); + const websiteURLStr = websiteURL.toString(); + return ( + {websiteURLStr} + ); + } catch { + // Fall back to returning string. + return tokenInfo.application.website; + } + }, [tokenInfo.application.website]); + + const created = useMemo(() => { + const createdAt = new Date(tokenInfo.created_at); + return ; + }, [tokenInfo.created_at]); + + const lastUsed = useMemo(() => { + if (!tokenInfo.last_used) { + return "unknown/never"; + } + + const lastUsed = new Date(tokenInfo.last_used); + return ; + }, [tokenInfo.last_used]); + const [ invalidate, invalidateResult ] = useInvalidateTokenMutation(); return ( @@ -140,22 +174,22 @@ function TokenInfoListEntry({ tokenInfo }: TokenInfoListEntryProps) {
App name:
{tokenInfo.application.name}
- { tokenInfo.application.website && + { appWebsite &&
App website:
-
{tokenInfo.application.website}
+
{appWebsite}
}
-
Token scope:
+
Scope:
{tokenInfo.scope}
-
Token created at:
+
Created:
{created}
-
Token last used:
+
Last used:
{lastUsed}