diff --git a/apps/docs/docs/management/workshop/index.mdx b/apps/docs/docs/management/workshop/index.mdx index e9d4acd2c..9df9874c9 100644 --- a/apps/docs/docs/management/workshop/index.mdx +++ b/apps/docs/docs/management/workshop/index.mdx @@ -95,8 +95,11 @@ irreversible development reset. GitHub needs only the central callback `https:///api/oauth2-redirect`. Keep PocketBase origins unrestricted unless every self-hosted Homarr caller is explicitly listed. Configure both `GITHUB_CLIENT_ID` and `GITHUB_CLIENT_SECRET`; supplying only one is a startup error. Set `WORKSHOP_PUBLIC_ORIGIN` in production so generated -links and email use the public host. Workshop uses the OAuth provider username as the public display name instead of -the profile's full name. Configure SMTP for comment, report, and removal notices. +links and email use the public host. Workshop stores only the OAuth provider username in `users.githubUsername`, and +users cannot rename it. Map **OAuth2 username** to `githubUsername`; leave OAuth2 id, full name, and avatar mappings +empty. Profile and avatar URLs are derived from `https://github.com/` and +`https://github.com/.png`, so PocketBase does not store duplicate profile metadata or avatar files. Configure +SMTP for comment, report, and removal notices. The public URL contract is: diff --git a/apps/docs/src/components/workshop/DetailComments.tsx b/apps/docs/src/components/workshop/DetailComments.tsx index d0ae971fb..381411ff3 100644 --- a/apps/docs/src/components/workshop/DetailComments.tsx +++ b/apps/docs/src/components/workshop/DetailComments.tsx @@ -3,6 +3,7 @@ import { IconCheck, IconEdit, IconMessageCircle, IconRefresh, IconSend, IconTras import type { WorkshopComment } from "@site/src/lib/pocketbase"; import { getWorkshopBackend } from "@site/src/lib/pocketbase"; +import { githubAvatarUrl, githubProfileUrl } from "@homarr/workshop/schema"; import type { WorkshopUser } from "@homarr/workshop/schema"; import { errorMessage } from "@site/src/lib/utils"; @@ -158,13 +159,12 @@ export const CommentsSection = ({ submissionId, backend, currentUser, onRequireA const canDelete = ownComment || currentUser?.isAdmin === true; const isEditing = editingId === comment.id; const edited = comment.updated !== comment.created; - const authorName = ownComment ? (currentUser?.displayName ?? comment.authorName) : comment.authorName; - const avatarUrl = ownComment - ? (currentUser?.avatarUrl ?? comment.authorAvatarUrl) - : comment.authorAvatarUrl; - const profileUrl = ownComment - ? (currentUser?.githubProfileUrl ?? comment.authorGithubProfileUrl) - : comment.authorGithubProfileUrl; + const authorGithubUsername = ownComment + ? (currentUser?.githubUsername ?? comment.authorGithubUsername) + : comment.authorGithubUsername; + const authorName = authorGithubUsername || "Community member"; + const avatarUrl = githubAvatarUrl(authorGithubUsername); + const profileUrl = githubProfileUrl(authorGithubUsername); return (
- {currentUser?.avatarUrl && } + {currentUser?.githubUsername && } - {avatarFallback(currentUser?.displayName ?? "Guest")} + {avatarFallback(currentUser?.githubUsername ?? "Guest")}