sync: upstream v0.30.6 - #215
Open
AminDhouib wants to merge 124 commits into
Open
AminDhouib wants to merge 124 commits into
AminDhouib wants to merge 124 commits into
Conversation
- Integrated Dropzone component into handle-organization.tsx. - Resolved dialog auto-close bug by decoupling Dialog from DropdownMenu trigger. - Added DOMPurify to sanitize uploaded SVG logos preventing XSS. - Implemented client-side compression via canvas to resize raster images to 256x256 WebP. - Enhanced UX with instant logo preview, masked base64 input strings, and a quick-clear button. - Updated Dropzone to accept classNameContent for local height overrides.
# Conflicts: # apps/dokploy/components/proprietary/whitelabeling/whitelabeling-provider.tsx # apps/dokploy/pages/_app.tsx
Adds Infomaniak alongside Cloudflare, AWS Route53 and Porkbun, following the
existing DnsClient interface in packages/server/src/utils/dns/.
- infomaniak.ts implements listZones, listRecords, upsertRecord, updateRecord,
deleteRecord and testConnection against the Infomaniak API. Zones come from
/1/product?service_name=domain and records from the v2 /2/zones/{zone}/records
endpoints, which are keyed by zone name rather than by product id.
- A new `infomaniak` value was added to the DnsProviderType enum along with an
infomaniakDnsConfigSchema (apiToken) in the discriminated union, plus the
Drizzle migration for the enum change.
- The token is masked/merged like the other providers in services/dns-provider.ts.
- UI: Infomaniak icon and API Token field in the DNS provider dialog, plus
registration in the provider selector.
Infomaniak's `source` is relative to the zone (empty for the apex), so record
names are translated between Dokploy's fully-qualified format and Infomaniak's
subdomain-only format internally, with the trailing dot handled. TXT targets are
stored quoted by the API and are unquoted on read / quoted on write so that
editing a record does not stack quotes on every save.
Also fills in the missing Porkbun label in show-dns-providers.tsx, which fell
back to displaying the raw enum value.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Adds OVHcloud alongside Cloudflare, AWS Route53 and Porkbun, following the
existing DnsClient interface in packages/server/src/utils/dns/.
- ovh.ts implements listZones, listRecords, upsertRecord, updateRecord,
deleteRecord and testConnection against the /domain/zone endpoints of the
OVHcloud API, on any of its seven regional endpoints (ovh-eu/ca/us, kimsufi
and soyoustart).
- A new `ovh` value was added to the DnsProviderType enum along with an
ovhDnsConfigSchema (endpoint, applicationKey, applicationSecret, consumerKey)
in the discriminated union, plus the Drizzle migration for the enum change.
- The application secret and the consumer key are masked/merged like the other
providers' secrets in services/dns-provider.ts.
- UI: OVHcloud icon, an endpoint selector and the three credential fields in the
DNS provider dialog, plus registration in the provider selector.
Three OVH-specific behaviours are handled explicitly:
- Requests are signed with `$1$` + sha1(applicationSecret+consumerKey+method+
url+body+timestamp). The timestamp comes from the API's own clock via an
unauthenticated GET /auth/time, since a host clock a few seconds off would get
every call rejected; the measured drift is cached per endpoint for an hour.
- OVH only applies zone changes once the zone is explicitly refreshed, so every
successful create, update and delete is followed by POST /domain/zone/{zone}
/refresh.
- The record update payload carries no fieldType, so changing a record's type
replaces the record (DELETE then POST) and returns the new id.
The record listing endpoint returns ids only, so each record is fetched
individually with the fan-out capped at 8 concurrent requests.
Also fills in the missing Porkbun label in show-dns-providers.tsx, which fell
back to displaying the raw enum value.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Verified against a live Infomaniak account: the API returns `source: "."` for
apex records, not "" as assumed.
Reading them back produced a doubled dot ("..example.com"), and writing "" meant
an apex upsert never matched the existing record, so it would have created a
duplicate apex record instead of updating it.
toSource now emits "." for the apex and toFqdn accepts ".", "" and "@" so a
hand-written record still round-trips.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
toSource always writes the apex as ".", but listRecords already accepted "" and "@" as apex spellings on read. The upsert lookup compared sources strictly, so a record stored under one of the other spellings would not have matched and the upsert would have created a duplicate apex record instead of updating it. Normalize the candidate's source before comparing, so read and match agree. Reported by Greptile on Dokploy#5257. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Changing a record's type deletes the record then recreates it with the new type, because OVH's update payload carries no fieldType. If the creation failed the name was left with nothing and no rollback. The delete still has to come first, since OVH rejects a CNAME that would sit alongside other data on the same name. So on a failed creation the original record is put back from the copy already fetched before the delete, and the original error is rethrown. If the restore fails too, the error names the record that has to be recreated by hand. Reported by Greptile on Dokploy#5258. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
listZones used /1/product, which lego uses but the API docs don't: it is the legacy singular route, it returns no pagination metadata, and it 401s for at least some tokens. The documented /1/products returns `total`, `pages`, `items_per_page` and `page`, and defaults to 15 domains per page, so an account with more domains than that would silently lose zones. Switch to the plural endpoint and walk every page. Verified against a live account: forcing per_page=2 collects all 5 domains across 3 pages with no duplicates. Also inline the single-use createdId helper. Both reported by @narcisonunez on Dokploy#5257. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
OVH matches access rules per exact path: a `GET /domain/zone/*` rule grants the
subtree but not the bare `GET /domain/zone` that listZones and testConnection
call. Verified against a live account with a consumer key carrying that single
wildcard rule:
GET /domain/zone -> 403 This call has not been granted
GET /domain/zone/ -> 200
GET /domain/zone/{zone}/record -> 200
The form only asked for rights on `/domain/zone/*`, so a token created by
following it could not list zones at all, and the failure surfaced as a bare
"This call has not been granted" that points nowhere.
The hint now lists the five rights verbatim, and a token missing the root one
gets an error that names it instead of echoing OVH's message.
Reported by @narcisonunez on Dokploy#5258.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- Sanitize customCss in _document.tsx to prevent XSS breakouts by stripping </style> tags. - Remove SSR favicon fetching to prevent SSRF and internal network scanning, falling back to client-side fetching.
canary landed its own 0190 (0190_nappy_anita_blake), which collides with this branch's 0190_perpetual_red_skull. Renaming would not have been enough: drizzle applies migrations by comparing timestamps against the last applied one, so this branch's older `when` would have been silently skipped on any deployment that had already run canary's 0190, leaving the enum without its new value. Regenerated as 0191_cool_christian_walker with a current timestamp.
canary landed its own 0190 (0190_nappy_anita_blake), which collides with this branch's 0190_even_mastermind. Renaming would not have been enough: drizzle applies migrations by comparing timestamps against the last applied one, so this branch's older `when` would have been silently skipped on any deployment that had already run canary's 0190, leaving the enum without its new value. Regenerated as 0191_elite_ultragirl with a current timestamp.
Reduce trial duration from 14 to 7 days
…gnment fix(ui): align close button in web server update modal
Fixes Dokploy#5279. The Domains table (and grid) view mounts one AddDomain instance per row for the edit action. Its 4 queries (domain.one, application.one/compose.one, domain.canGenerateTraefikMeDomains, compose.loadServices) ran unconditionally on mount instead of only when the edit dialog is open, so any table interaction that causes a re-render (typing in the host filter, sorting, toggling columns) fired all 4 queries for every domain row again.
…-and-misc-bugs fix(domains): stop AddDomain queries flooding the API in table view
better-auth's account-linking guard requires either the IdP asserting email_verified or the sso_provider row being domainVerified before it will link an SSO login to an existing local user with the same email. Entra ID never asserts email_verified (neither via its OIDC userinfo endpoint nor via SAML attributes), and Dokploy never persisted domainVerified at all, so linking was permanently impossible for any Entra-backed provider (OIDC or SAML) regardless of the local user's own emailVerified state. Add the domainVerified column, defaulting to true — Dokploy already scopes providers to an admin-configured domain and gates registration behind enterprise/admin permissions, so that domain match (still enforced by better-auth's validateEmailDomain check) is trust enough. Fixes Dokploy#5099
…ed-trust fix(sso): trust admin-configured SSO providers for account linking
… existing records Previously, upsertRecord matched only by type and name, silently overwriting any existing record of the same type/name with different content. This caused data loss when users had multiple records of the same type (e.g. multiple TXT records for SPF + site verification). Now upsertRecord also checks the record content/target before deciding to update. If the content differs, a new record is created alongside the existing one instead of replacing it. Affected providers: Cloudflare, Porkbun, Infomaniak, OVH. Tests updated accordingly.
…d SRV/CAA records
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
* feat: add dynamic open graph metadata for enterprise whitelabeling
…d-filter perf(dns): filter Infomaniak records server-side when upserting
…eserve-existing-records # Conflicts: # packages/server/src/utils/dns/infomaniak.ts
…xisting-records fix(dns): match record content in upsertRecord to prevent overwriting existing records
…cret-references fix(vault): expand Infisical secret references when listing secrets
An Infisical provider is pinned to one non-recursive `secretPath`, so reading
two folders means two providers, two machine identities and two sets of
credentials to rotate. This lets a reference name the folder instead:
${{vault.my-provider.external/sentry:SENTRY_DSN}}
`<path>:<KEY>` mirrors the HashiCorp client in this directory, which already
documents that exact format. A relative path resolves against the provider's
`secretPath`, a leading slash is absolute, and a ref without a colon keeps its
current meaning — the whole ref is the secret name at the provider's own path.
A dot cannot be the separator here: Infisical accepts dots inside secret names
(`A.B.C` is a valid key), so `provider.a.b.C` cannot be split unambiguously
and would silently break anyone using such a name.
Refs are grouped by resolved path so each path is listed once, and the login
happens once per batch rather than once per path.
Tests cover the bare ref, relative and absolute paths, a provider at `/`,
grouping with a single login, the error naming the path, and a malformed ref.
…reference feat(vault): address an Infisical folder from the reference
/etc/docker/daemon.json isn't mounted into the dokploy container, only docker.sock is, so cat-ing it always failed silently. Read the effective config over the already-mounted socket instead. Fixes Dokploy#5383
…s-pools fix(server-health): detect custom default-address-pools via docker info
🚀 Release v0.30.6
121 upstream commits since v0.30.5. Version set to v0.30.6-community.1. Conflict resolutions (16 files): - .claude/skills/fix-issue/SKILL.md: modify/delete. The fork deleted upstream's .claude skill files on purpose; kept deleted. - apps/dokploy/drizzle/meta/0191..0195_snapshot.json (add/add): kept ours. Upstream's colliding 0191-0195 .sql files and journal entries were dropped and their schema delta re-issued as the fork's 0201 (playbook Drizzle rule 4, as at v0.30.3 and v0.30.5). - apps/dokploy/package.json: version v0.30.6-community.1. Kept the fork's patched next/sharp/js-yaml pins from #213 (next 16.3.3 > upstream 16.3.0); took upstream's other dependency changes. - Same-change collisions - the fork had already ported upstream Dokploy#4769 (whitelabeling FOUC, 2035eed) and Dokploy#4765 (org logo drag-and-drop, 625b42d) before they merged upstream. Upstream's final versions win in pages/_document.tsx, server/api/routers/proprietary/whitelabeling.ts, components/ui/dropzone.tsx and components/dashboard/organization/ handle-organization.tsx, including upstream's extracted utils/ image-processing.ts, utils/sanitize-svg.ts, utils/create-server-helpers.ts and components/shared/truncate-tooltip.tsx, and the removal of whitelabeling-provider.tsx. The fork's organization-description feature was re-applied on top of upstream's handle-organization.tsx. - pages/index.tsx, register.tsx, invitation.tsx, send-reset-password.tsx: took upstream's structure (createServerSideHelpers now lives in utils/create-server-helpers.ts), then re-applied the fork behaviours: validated post-login redirect carried through social/SSO sign-in for the MCP consent return path, social login on self-hosted when configured, password reset allowed on self-hosted, and the awaited-redirect login fix. - components/dashboard/application/domains/handle-domain.tsx: applied upstream's small 0f28775 diff (defer the AddDomain queries until the dialog opens) onto the fork's version, keeping every fork domain feature. - packages/server/src/lib/auth.ts: both sides survive. Upstream's SSO enforcement on the server-side sign-in/passkey/signup endpoints runs first in hooks.before, followed by the fork's MCP OAuth DCR and consent-proof gates; the fork's hooks.after refresh-rotation clamp is unchanged. The path sets are disjoint. Notable upstream change: v0.30.6 (8c9e473) reverts the v0.30.5 default Docker build-context break - getDockerContextPath returns null again when unset and builders/docker-file.ts falls back to the Dockerfile's directory.
Upstream v0.30.6 added 0191_cool_christian_walker, 0192_light_lake, 0193_chemical_the_liberteens, 0194_acoustic_prima and 0195_classy_whirlwind. The fork has released migrations at all five of those numbers, so instances have already run the fork's copies. Per docs/UPSTREAM_SYNC.md Drizzle rule 4, upstream's five .sql files, five snapshots and five journal entries were dropped and the schema delta regenerated into the fork's next free slot. 0201 contains exactly the upstream delta and nothing else: DnsProviderType += infomaniak, ovh VaultProviderType += aws-parameter-store (BEFORE doppler) webServerSettings.whitelabelingConfig default gains ogImageUrl sso_provider.domain_verified boolean DEFAULT true NOT NULL Guarded with ADD VALUE IF NOT EXISTS / ADD COLUMN IF NOT EXISTS, the same pattern 0199_complex_mantis used for porkbun and phase. The SET DEFAULT is naturally idempotent. No DROP and no fork object in the generated SQL, so the schema merge preserved the fork columns and tables. Journal is monotonic in when, carries no upstream 0191-0195 entries, and 0201 (1789444271863) sorts after 0200_handy_lifeguard (1789011785969).
Four new sections and two corrections to the playbook: - Same-change collisions on upstream Dokploy#4769 / Dokploy#4765, which the fork had already ported. Upstream wins in _document.tsx, whitelabeling.ts, dropzone.tsx and handle-organization.tsx; the two accepted behavioural deltas (favicon data-URI inlining, metaTitle -> appName/ogImageUrl) are written down, and the one fork feature that had to be re-applied on top (organization descriptions). - The four login pages rebuilt on upstream's generateServerSideHelper, with the exact fork behaviours re-applied to each and the commit that introduced them. - Upstream's SSO enforcement coexisting with the fork's MCP OAuth hooks in better-auth hooks.before, and the enforceSSO/social-login interaction. - Drizzle rule 4 applied a fourth time: upstream 0191-0195 -> fork 0201. Corrections: - The v0.30.5 BREAKING build-context change was reverted upstream at v0.30.6, so that section now says so; it only ever shipped in v0.30.5-community.1. - webServerSettings.domainRestrictionConfig was missing from the fork-columns ledger even though it is a fork column on an upstream table. Added.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Syncs the fork to upstream release tag v0.30.6 (121 upstream commits since
v0.30.5). Version set tov0.30.6-community.1.Merge commit, never a rebase, per
docs/UPSTREAM_SYNC.md. Do not merge this yet — merge, release and deploy are the maintainer's call.Summary
Headline upstream features in this release:
DnsProviderType+=infomaniak,ovh)VaultProviderType+=aws-parameter-store)</style>tag XSS breakout scrub (including</style/>and whitespace variants), SVG sanitising on upload — plus OG metadata (ogImageUrl, absolute fallback OG image for social scrapers)enforceSSOis on; SSO account-linking trustdocker infoover the socket instead of/etc/docker/daemon.json(which isn't mounted into the container)nanoidbump; trial 14 → 7 days (cloud-only, no effect self-hosted)Also notable: v0.30.6 (
8c9e473b4) reverts the v0.30.5 default Docker build-context break.getDockerContextPathreturnsnullagain when unset andbuilders/docker-file.tsrestores the fallback to the Dockerfile's own directory. That break only ever shipped inv0.30.5-community.1. Users who setdockerContextPathexplicitly to work around it are unaffected — an explicit context is still honoured — and do not need to revert their config.Conflicts and resolutions (16 files)
.claude/skills/fix-issue/SKILL.md.claudeskill files on purpose. Verified.claude/settings.jsonwas not resurrected either.drizzle/meta/0191..0195_snapshot.json(add/add ×5)apps/dokploy/package.jsonv0.30.6-community.1. Kept the fork's #213 security pins (next16.3.3 > upstream's 16.3.0, plus thesharp@<0.35.4andjs-yaml@4overrides); took upstream's other dependency changes.pages/_document.tsxserver/api/routers/proprietary/whitelabeling.tscomponents/dashboard/organization/handle-organization.tsxpages/index.tsxpages/register.tsxpages/invitation.tsxawait router.push(...).pages/send-reset-password.tsx!IS_CLOUDredirect (self-hosted password reset).components/dashboard/application/domains/handle-domain.tsx0f28775a1diff applied onto it.packages/server/src/lib/auth.tsSame-change collisions
The fork had already ported two upstream PRs before they merged upstream — Dokploy#4769 (whitelabeling FOUC, fork commit
2035eed43) and Dokploy#4765 (org logo drag-and-drop,625b42dff), both by Yash Kumar. Upstream's further-developed versions now win. Taken wholesale: upstream's extractedutils/image-processing.ts,utils/sanitize-svg.ts,utils/create-server-helpers.ts,components/shared/truncate-tooltip.tsx, and the removal ofwhitelabeling-provider.tsx(confirmed zero remaining references). Upstream also adopted the fork'sclassNameContentprop oncomponents/ui/dropzone.tsxverbatim, so that file is now byte-identical to upstream and both fork callers still work.Two behavioural deltas accepted under theirs-wins, both documented in the playbook:
faviconUrl. Upstream's version is otherwise a superset (OG metadata + the XSS/SVG fixes).whitelabelingConfig.metaTitleis gone — upstream drives the document title fromappNameand addsogImageUrl.Fork behaviours re-applied on top of upstream's files
index.tsx—getPostLoginDestination(router.query)replaces every/dashboard/homeliteral (4 client redirects + 2getServerSidePropsredirects) so the validated post-login target survives password, passkey, 2FA, backup-code, social and SSO sign-in. This is the MCP consent return path (ec4e90253,4af3e723d) — losing it would break the remote-MCP OAuth flow. PlusSocialLoginButtonson self-hosted when GitHub/Google env vars are configured (9e63ae180),callbackURLthreaded into both<SignInWithSSO>branches, and the per-branchsetIsLoading(false)calls that keep the button spinning across the awaited redirect (94be4ca34).register.tsx— self-hosted social login (9e63ae180).send-reset-password.tsx— password reset allowed on self-hosted (03d51628c).invitation.tsx—await router.push(...)(94be4ca34).handle-organization.tsx— organization descriptions (d8ff0a7a7), stored in better-auth's opaquemetadataJSON. The fork's{!isControlled && <DialogTrigger>}guard was deliberately not re-applied: upstream ships the same controlledopen/onOpenChangeprops and renders the trigger unconditionally, and no caller uses controlled mode.handle-domain.tsx— every fork domain feature kept (wildcard domains + Traefik v3HostRegexp, user-owned wildcard base, wildcard domain restriction, Cloudflare Tunnel publishing + Cloudflare Access, custom certificate provider display). Upstream's diff — defer the AddDomain queries until the dialog opens — was applied onto ours; the resulting diff vscanaryis exactly upstream's fiveenabled:changes and nothing else.auth.ts— both sides survive. Upstream's SSO enforcement runs first inhooks.before(a hard deny for the whole request), then the fork's MCP OAuth gates (/mcp/registerDCR policy,/mcp/authorizeconsent proof); the fork'shooks.afterrefresh-rotation clamp,buildMemberSession, 30-day sliding sessions and session-rejection logging are untouched. The two path sets are disjoint, so ordering is readability, not behaviour.Migrations
Fourth application of the playbook's Drizzle rule 4. Upstream added
0191_cool_christian_walker,0192_light_lake,0193_chemical_the_liberteens,0194_acoustic_primaand0195_classy_whirlwind— but the fork has released migrations at all five of those numbers, so instances have already run the fork's copies and taking upstream's would strand production. Upstream's five.sqlfiles, five snapshots and five_journal.jsonentries were dropped, and the schema delta regenerated into the fork's next free slot as0201_steep_sage:Guards follow the
0199_complex_mantispattern (ADD VALUE IF NOT EXISTS/ADD COLUMN IF NOT EXISTS); theSET DEFAULTis naturally idempotent. None of the five upstream migrations is a data backfill, so nothing had to be hand-carried this time.Verified:
DROPand touches no fork object — the proof that the schema merge preserved every fork column and table.0201still hasorganization.wildcard_domain,project.wildcardDomain,project.useOrganizationWildcard,webServerSettings.domainRestrictionConfig, the threeoauth_*MCP tables and the threebuild_policy_*tables from feat(build-policy): enforced remote builds, registry push, deploy-by-digest, queue coalescing, required checks #209's0200._journal.jsonis monotonic inwhen, carries no upstream0191–0195entries, and0201(1789444271863) sorts after0200_handy_lifeguard(1789011785969)..gitattributesenforces it).Silent hazards found
webServerSettings.domainRestrictionConfigwas missing from the fork-columns ledger in the playbook, even though it is a fork column on an upstream-owned table — exactly the class of drift the ledger exists to prevent. It survived this merge, but it was surviving by luck rather than by check. Added to the ledger.BREAKINGbuild-context section was stale: upstream reverted that change at v0.30.6. The playbook now says so, since it changes the release notes for this release.generateTraefikMeDomain(the v0.30.5 trap): both call sites still pass the fork's 4thprojectIdargument and read.domain. No new upstream call sites in this release.organization.ts,whitelabeling.ts) and neither adds a procedure, so the fork's MCP scope map needed no new entries — confirmed by the tool→scope snapshot test passing unchanged. No scope was loosened.organization.tsauto-merged correctly: upstream'sname: z.string().min(1)landed on bothcreateandupdatewhile the fork'sdescriptioninput survived on both.A delta audit (fork's diff-vs-upstream before the merge vs after) flagged only 13 files as having lost fork lines, and every one is accounted for: the 5 discarded upstream drizzle snapshots, the 4 same-change collision files (delta correctly → 0), and the 4 login pages +
handle-organization.tsxwhere upstream absorbed boilerplate and only the genuine fork behaviours remain. No fork code was lost anywhere else.Verification
pnpm installpnpm --filter=dokploy run typecheckpackages/server, no output)pnpm --filter=dokploy run build-serverpnpm --filter=dokploy test -- run__test__/mcp/(scopes + tool→scope snapshot)next@16.3.3,sharp@0.35.4,js-yaml@4.3.2✅The 11 local failures are in 5 files, all of which the merge does not touch — neither the test files nor their subjects — and are the known Windows/Docker environment class the playbook documents:
__test__/deploy/application.real.test.ts(5) — needs Docker, git and nixpacks__test__/server/server-setup.test.ts(3) —command -v awk(no POSIX shell)__test__/backups/restore-use-statement.test.ts(1) —execSyncof a sed/awk pipeline__test__/compose/compose-project-directory.test.ts(1) — POSIX path assertions__test__/wss/readValidDirectory.test.ts(1) — POSIX path assertionsCI on Linux is the authority for these.
Release notes input
dockerContextPathto work around the v0.30.5 regression you can leave it as-is — explicit contexts are still honoured.<style>tag, and uploaded SVG logos are sanitised. New Open Graph metadata (custom OG image, description) so shared links render your branding.enforceSSOon, password, social and passkey sign-in and email signup are rejected at the auth layer, not just hidden in the UI. Note this also disables the fork's self-hosted social login buttons when enabled.next16.3.3 (two critical RCE advisories),sharpandjs-yamlpins are carried forward over upstream's oldernext16.3.0.