diff --git a/src/routes/ui/service-detail.js b/src/routes/ui/service-detail.js index b3f2168..77ef1e2 100644 --- a/src/routes/ui/service-detail.js +++ b/src/routes/ui/service-detail.js @@ -60,6 +60,17 @@ router.get('/:id', (req, res) => { const displayName = serviceModule?.displayName || serviceInfo?.name || account.service; const icon = getServiceIcon(account.service); + // OAuth re-auth route (null for non-OAuth services) + const oauthRetryRoutes = { + youtube: '/ui/youtube/retry', + google_calendar: '/ui/google/retry', + fitbit: '/ui/fitbit/retry', + linkedin: '/ui/linkedin/retry', + reddit: '/ui/reddit/retry', + mastodon: '/ui/mastodon/retry' + }; + const retryRoute = oauthRetryRoutes[account.service] || null; + // Build credential fields const creds = account.credentials || {}; const credFields = Object.keys(creds).map(key => { @@ -79,6 +90,7 @@ router.get('/:id', (req, res) => { displayName, icon, credFields, + retryRoute, escapeHtml, renderAvatar }); diff --git a/src/routes/ui/services.js b/src/routes/ui/services.js index 1e3d0b4..4d6e1af 100644 --- a/src/routes/ui/services.js +++ b/src/routes/ui/services.js @@ -175,12 +175,23 @@ export function renderConfiguredCards(accounts) { const displayName = svcModule?.displayName || serviceId; const icon = getServiceIcon(serviceId); - const accountRows = svcAccounts.map(acc => ` + const accountRows = svcAccounts.map(acc => { + const retryRoute = getRetryRoute(serviceId); + const { hasToken, hasCredentials } = acc.status || {}; + const reauthBtn = (retryRoute && hasCredentials) ? ` +
+ + +
` : ''; + return `
${escapeHtml(acc.name)} - Details -
- `).join(''); +
+ ${reauthBtn} + Details +
+ `; + }).join(''); return `
@@ -194,6 +205,21 @@ export function renderConfiguredCards(accounts) { }).join('\n'); } +/** + * Get the OAuth retry/re-auth route for a service, or null if not an OAuth service. + */ +function getRetryRoute(service) { + const routes = { + youtube: '/ui/youtube/retry', + google_calendar: '/ui/google/retry', + fitbit: '/ui/fitbit/retry', + linkedin: '/ui/linkedin/retry', + reddit: '/ui/reddit/retry', + mastodon: '/ui/mastodon/retry' + }; + return routes[service] || null; +} + function getServiceIcon(service) { const icons = { github: '/public/icons/github.svg', diff --git a/views/pages/service-detail.ejs b/views/pages/service-detail.ejs index 1a18eb5..c1fcdf8 100644 --- a/views/pages/service-detail.ejs +++ b/views/pages/service-detail.ejs @@ -8,6 +8,12 @@

Credentials

Stored credentials for this service instance.

+ <% if (retryRoute) { %> +
+ + +
+ <% } %> <% if (credFields.length === 0) { %>

No credentials stored.

<% } else { %>