Use the same classes the login page puts on its own buttons so the SSO link
picks up the theme styling, and note that copying a real button's markup does
not work: a button cannot navigate without an href and DOMPurify removes
onclick. Warn against copying btnQuick, which is the Quick Connect binding
hook rather than styling.
Co-Authored-By: Claude <noreply@anthropic.com>
The documented snippet relied on is="emby-linkbutton", but Jellyfin renders the
login disclaimer through markdown-it and then DOMPurify, which strips the is
attribute. The anchor therefore never became a button component and rendered as
a plain link.
Drop the attribute, keep the classes so the theme styles the button, and
document the Custom CSS the disclaimer needs: .disclaimerContainer is not a
block by default, so a "block" button cannot stretch to the width of the other
login buttons, and the anchor colour rule outranks .emby-button.
Co-Authored-By: Claude <noreply@anthropic.com>
Pocket ID exposes an avatar through the standard picture claim, pointing at
/api/users/{id}/profile-picture.png. On login the plugin now fetches that URL
and writes it to the Jellyfin user's profile image, so SSO users get their
avatar without setting one by hand.
The picture is fetched anonymously. The access token is deliberately not sent,
because the address ultimately originates from a token payload and must not be
treated as a trusted destination for credentials. Non-http(s) URLs, non-image
content types and anything over 5 MB are rejected, and an identical image is
not rewritten so the image cache is left alone. Any failure is logged and
swallowed: a broken avatar must never block a login.
Controlled by the new "Sync the profile picture" setting, on by default, with
the claim name configurable for providers that do not use "picture".
Co-Authored-By: Claude <noreply@anthropic.com>
actions/checkout leaves refs/tags/<tag> as a lightweight ref pointing straight
at the commit, so `git tag -l --format='%(contents)'` fell through to the commit
message. v1.0.4.0 shipped with the entire commit message as its changelog.
Re-fetch the tag ref so the annotated object is present, and only read a message
when the ref really is a tag object. Use subject+body instead of %(contents) so
a signature would not end up in the changelog, and fall back to build.yaml when
the tag is lightweight or its message is empty.
Co-Authored-By: Claude <noreply@anthropic.com>
The release workflow was copied from another project and could not succeed on
any tag: it installed the .NET 8 SDK for a net9.0 project, published a
JellyfinSso.csproj that does not exist, called a missing update_manifest.py,
and zipped the entire publish tree instead of the three DLLs declared in
build.yaml.
Replace it with a tag-driven release:
- Build with the .NET 9 SDK, injecting the tag version via -p:Version,
-p:AssemblyVersion and -p:FileVersion so the assembly no longer carries a
hardcoded 1.0.3.0.
- Package via scripts/build_plugin.py, which emits the JPRM layout Jellyfin
expects: the build.yaml artifacts plus a generated meta.json. The previous
zips shipped without meta.json, which only worked for repository installs
because Jellyfin synthesises one from the folder name.
- Update manifest.json via scripts/update_manifest.py, keeping build.yaml as
the single source of truth for plugin metadata.
- Commit the zip and manifest to main and attach the zip to the Gitea release.
Pushing uses the injected token, falling back to a RELEASE_TOKEN secret when
the built-in one lacks write access.
Also fix the published download URLs. manifest.json and the README pointed at
pascallinxweiler/jellyfinplugin, which 404s; the repository is jellyfinsso, so
the plugin repository could not be added to Jellyfin and no version could be
downloaded. The workflow now derives the URL from GITHUB_REPOSITORY.
Add a build workflow so main and pull requests are compiled and packaged.
Co-Authored-By: Claude <noreply@anthropic.com>
SSO login for an existing admin whose token lacked the admin role was
silently demoting the account, locking admins out of the dashboard.
Missing admin role now leaves the flag alone unless
RevokeAdminWithoutRole is enabled.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Server 10.11 moved PermissionKind to Jellyfin.Database.Implementations.Enums,
SetPermission to a Jellyfin.Data extension, and ChangePassword now takes a
user id. Plugin built against 10.10 failed to load silently.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
OpenID Connect SSO for Jellyfin 10.10 (net8.0). Authorization code flow
with PKCE via IdentityModel.OidcClient, automatic user creation with
random password, role based admin/access mapping, plugin repo manifest.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>