Skip to content

feat: v5#61

Merged
steveiliop56 merged 35 commits into
mainfrom
feat/v5
Mar 2, 2026
Merged

feat: v5#61
steveiliop56 merged 35 commits into
mainfrom
feat/v5

Conversation

@steveiliop56
Copy link
Copy Markdown
Member

@steveiliop56 steveiliop56 commented Feb 25, 2026

Summary by CodeRabbit

  • New Features

    • OIDC server docs, v5 migration guide and config migrator, plus an animated Active Instances counter on the homepage
  • Documentation

    • Major docs overhaul: new CLI & configuration references, v5 changelog, Kubernetes, Zitadel/Google/GitHub/PocketID guides, TOTP, LDAP groups, access-controls, and many getting-started updates
  • Refactor

    • Site migrated to Astro with a new theme and reorganized structure; legacy UI/layout pieces removed

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Feb 25, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This PR migrates the docs site from a React Router / Fumadocs stack to Astro + Starlight: it removes the React app, routes, and many UI primitives; adds Astro config, pages, content collections, styles, and utilities (config migrator and instance fetcher); and reorganizes MDX docs and assets.

Changes

Cohort / File(s) Summary
Platform / Build
astro.config.mjs, package.json, tsconfig.json, vite.config.ts, .github/workflows/deploy.yml
Add Astro + Starlight config and integrations, update scripts/dependencies to Astro ecosystem, remove Vite/react-router config and the GitHub Pages workflow.
App Shell & Routing Removed
app/root.tsx, app/routes.ts, react-router.config.ts, app/routes/*
Delete React Router app shell, root layout, error boundary, and route modules (home, discord, docs, search).
Fumadocs UI & Components Deleted
app/components/..., app/components/layout/..., app/components/ui/*, app/components/mdx/*, app/components/search.tsx, app/components/sidebar.tsx
Remove large set of UI primitives, layout components, TOC/mermaid/mdx helpers, toggles, navigation, sidebar, and related client code.
Utilities & Editor/Format Config Removed
app/lib/*, app/cli.json, app/app.css, .prettierrc, .prettierignore, .vscode/settings.json
Delete React-specific utilities, Tailwind/fumadocs CSS imports, CLI metadata, and some Prettier/VSCode config entries.
Source & Generated Artifacts Removed
source.config.ts, source.generated.ts, app/lib/source.ts
Remove fumadocs/source configuration and generated source artifacts used by the prior MDX pipeline.
Docs content removed → reorganized
content/docs/* (removed), src/content/docs/docs/**/* (added/updated), content/docs/meta.json
Purge old content tree; add reorganized Astro/Starlight docs, many MDX pages, convert callouts to admonitions, update images/paths, and rename env vars to TINYAUTH_*.
New Astro pages & content
src/pages/index.astro, src/content.config.ts, src/styles/*
Add Astro home page (InstancesCount web component), content collection config, and site styles (theme/home/migrator).
New utilities & UI
src/lib/4-to-5-config-migrator.ts, src/lib/get-instances.ts, src/content/docs/docs/breaking-updates/4-to-5-migrator.astro
Add v4→v5 config migrator, simple instances fetcher, and an interactive migrator UI component.
Home & legacy UI removed
app/components/layout/home/*, app/routes/home.tsx, app/docs/*
Remove previous Home layout, navbar/menu components, and home route implementation.
Formatting / Admonitions & content updates
many src/content/docs/docs/* files
Convert Callout components to Starlight/Markdown admonitions, standardize examples, and update many guides (OAuth, LDAP, OIDC, TOTP, changelog, references).

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

Possibly related PRs

Poem

🐰
I nibbled old routes and chewed through styles with glee,
Hopped from React hedgerows to Astro fields so free.
Fumadocs crumbs I swept away with nimble cheer,
New docs and migrators bloom — the burrow’s bright and clear. ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: v5' is directly related to the changeset, which implements a complete migration from a React Router-based documentation site to an Astro-based setup for version 5 of Tinyauth.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/v5

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@steveiliop56 steveiliop56 marked this pull request as ready for review February 27, 2026 19:48
@steveiliop56
Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Feb 27, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 11

Note

Due to the large number of review comments, Critical, Major severity comments were prioritized as inline comments.

🟡 Minor comments (19)
src/content/docs/docs/breaking-updates/3-to-4.mdx-150-154 (1)

150-154: ⚠️ Potential issue | 🟡 Minor

Fix wording: use hyphenated compound modifier.

At Line 153, “Container name based label discovery” should be “Container-name-based label discovery” for correct grammar and readability.

✏️ Suggested text fix
-  Container name based label discovery is no longer supported.
+  Container-name-based label discovery is no longer supported.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/content/docs/docs/breaking-updates/3-to-4.mdx` around lines 150 - 154,
Update the note text to use the hyphenated compound modifier: replace the phrase
"Container name based label discovery is no longer supported." with
"Container-name-based label discovery is no longer supported." in the block
containing the example `myapp.example.com` and the label
`tinyauth.apps.myapp.foo: bar` so the grammar and readability are corrected.
src/styles/theme.css-43-48 (1)

43-48: ⚠️ Potential issue | 🟡 Minor

border shorthand overrides preceding border-width.

The border: 1px solid on line 46 resets all border sub-properties, making border-width: 2px on line 45 dead code. The final border will be 1px, not 2px.

If you intended a 2px border, consolidate the properties:

🐛 Proposed fix
 .sl-markdown-content img {
     border-radius: 0.375rem;
-    border-width: 2px;
-    border: 1px solid;
-    border-color: var(--sl-color-gray-5);
+    border: 2px solid var(--sl-color-gray-5);
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/styles/theme.css` around lines 43 - 48, The CSS for .sl-markdown-content
img uses border-width: 2px followed by border: 1px solid which overrides it, so
change the declarations to a single consolidated border rule or keep
width/style/color separate; for example update the .sl-markdown-content img rule
to use border: 2px solid var(--sl-color-gray-5) (or remove the shorthand and
keep border-width: 2px plus border-style: solid and border-color:
var(--sl-color-gray-5)) so the intended 2px border is applied.
src/styles/home.css-8-10 (1)

8-10: ⚠️ Potential issue | 🟡 Minor

Selector logic appears incorrect.

The selector &:not(.content-panel:has(.sl-banner)) checks if main is not a .content-panel element, which is always true since main never has that class. This means .content-panel:first-of-type will always be hidden.

If the intent is to hide the first content panel when there's no banner present, the selector should be:

Proposed fix
-    &:not(.content-panel:has(.sl-banner)) .content-panel:first-of-type {
+    &:not(:has(.sl-banner)) .content-panel:first-of-type {
         display: none;
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/styles/home.css` around lines 8 - 10, The current selector
"&:not(.content-panel:has(.sl-banner)) .content-panel:first-of-type" is wrong
because it tests whether the parent itself has the .content-panel class; change
it to test whether the parent has a .sl-banner and hide the first panel only
when there's no banner. Replace that selector with "&:not(:has(.sl-banner))
.content-panel:first-of-type { display: none; }" so the rule hides the first
.content-panel only when the parent does not contain .sl-banner.
src/content/docs/docs/guides/pocket-id.mdx-53-60 (1)

53-60: ⚠️ Potential issue | 🟡 Minor

Inconsistent indentation in admonition content.

The content inside the :::note blocks has inconsistent indentation. Lines 54 and 58 have extra leading spaces that could cause rendering issues or look inconsistent. In Starlight/Astro, admonition content typically doesn't require extra indentation.

📝 Suggested fix
 :::note
-    Pocket ID should be accessed using HTTPS and a trusted certificate. In case this is not possible (e.g. self-signed certificates), you will need to use `TINYAUTH_OAUTH_PROVIDERS_POCKETID_INSECURE=true` in order for Tinyauth to skip the certificate check.
+Pocket ID should be accessed using HTTPS and a trusted certificate. In case this is not possible (e.g. self-signed certificates), you will need to use `TINYAUTH_OAUTH_PROVIDERS_POCKETID_INSECURE=true` in order for Tinyauth to skip the certificate check.
 :::

 :::note
-  Set the `TINYAUTH_OAUTH_AUTOREDIRECT` environment variable to `pocketid` to enable
+Set the `TINYAUTH_OAUTH_AUTOREDIRECT` environment variable to `pocketid` to enable
   automatic redirection to Pocket ID for Tinyauth-protected apps.
 :::
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/content/docs/docs/guides/pocket-id.mdx` around lines 53 - 60, Remove the
extra leading spaces inside both admonition blocks so the content lines align
directly under the ":::note" markers; specifically, unindent the lines
containing the TINYAUTH_OAUTH_PROVIDERS_POCKETID_INSECURE description and the
TINYAUTH_OAUTH_AUTOREDIRECT instruction so they match the other admonition line
spacing, ensuring the ":::note" blocks render consistently in Starlight/Astro.
src/content/docs/docs/getting-started.mdx-94-95 (1)

94-95: ⚠️ Potential issue | 🟡 Minor

Normalize TINYAUTH_AUTH_USERS examples to a valid, consistent format.

The sample in Line 95 does not match the documented username:hash[:totp] schema and can lead to invalid copy/paste configs. Use one copy-safe bcrypt-style example across both snippets.

Suggested doc patch
-    - TINYAUTH_AUTH_USERS=your-username-password-hash
+    - TINYAUTH_AUTH_USERS=user:$$2a$$10$$UdLYoJ5lgPsC0RKqYH/jMua7zIn0g9kPqWmhYayJYLaZQ/FTmH2/u # user:password

Also applies to: 137-138

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/content/docs/docs/getting-started.mdx` around lines 94 - 95, Replace the
inconsistent example for TINYAUTH_AUTH_USERS with a single, copy-safe example
that follows the documented username:hash[:totp] schema (e.g., using a
bcrypt-style hash); update both occurrences (the snippet containing
TINYAUTH_AUTH_USERS at the shown spot and the other instance around lines
137–138) so they use the same example format and include the variable name
TINYAUTH_AUTH_USERS for clarity.
src/content/docs/docs/reference/labels.mdx-42-42 (1)

42-42: ⚠️ Potential issue | 🟡 Minor

Use hyphenated compound adjective in label description.

Line 42 should use “comma-separated” (hyphenated) for grammatical correctness.

✏️ Proposed wording fix
-| `tinyauth.apps.[app].ldap.groups`                    | A comma separated list of LDAP groups required by a user to access the app.                                                            |
+| `tinyauth.apps.[app].ldap.groups`                    | A comma-separated list of LDAP groups required by a user to access the app.                                                            |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/content/docs/docs/reference/labels.mdx` at line 42, Update the
description for the label `tinyauth.apps.[app].ldap.groups` to use the
hyphenated compound adjective "comma-separated" instead of "comma separated";
locate the table row containing the `tinyauth.apps.[app].ldap.groups` key in
labels.mdx and replace the phrase so the description reads "A comma-separated
list of LDAP groups required by a user to access the app."
src/content/docs/docs/guides/ldap.mdx-68-68 (1)

68-68: ⚠️ Potential issue | 🟡 Minor

Fix malformed LDAP filter inline code.

Line 68 includes an extra leading quote in the filter snippet, which can mislead users when copying the filter.

🛠️ Proposed fix
-Tinyauth supports extracting the group information from the LDAP provider. This allows you to configure application groups straight from the LDAP server. Groups are extracted using the `"(&(objectclass=groupOfUniqueNames)(uniquemember=%s))` filter where `%s` is replaced by the username of the user attempting to log in. This filter should work with most LDAP servers.
+Tinyauth supports extracting the group information from the LDAP provider. This allows you to configure application groups straight from the LDAP server. Groups are extracted using the `(&(objectclass=groupOfUniqueNames)(uniquemember=%s))` filter where `%s` is replaced by the username of the user attempting to log in. This filter should work with most LDAP servers.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/content/docs/docs/guides/ldap.mdx` at line 68, Fix the malformed LDAP
filter inline code by removing the extra leading double-quote before the filter
snippet `"(&(objectclass=groupOfUniqueNames)(uniquemember=%s))` so it reads
`(&(objectclass=groupOfUniqueNames)(uniquemember=%s))`; update the inline code
in src/content/docs/docs/guides/ldap.mdx where the filter string appears to
ensure the backticks wrap only the filter text and no stray quote characters
remain.
src/content/docs/docs/guides/using-the-binary.mdx-24-32 (1)

24-32: ⚠️ Potential issue | 🟡 Minor

Avoid “latest stable” wording with a pinned tag example.

At Line 25, the text says “latest stable version” but the command pins v5.0.0, which will become stale. Prefer “a stable released tag” wording to keep this accurate.

Proposed wording update
 :::note
-It is recommended to use a tag when downloading the example `.env` file to ensure you are using the latest stable version and not a development one. For example:
+It is recommended to use a released tag when downloading the example `.env` file so your setup is reproducible and does not track development changes. For example:

 ```sh
 curl -o .env https://raw.githubusercontent.com/steveiliop56/tinyauth/refs/tags/v5.0.0/.env.example

-Will download the example .env file for the v5.0.0 tag.
+This downloads the example .env file for the v5.0.0 release tag.
:::

</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against the current code and only fix it if needed.

In @src/content/docs/docs/guides/using-the-binary.mdx around lines 24 - 32,
Replace the phrase "latest stable version" with "a stable released tag" and
update the explanatory sentence after the curl example (the paragraph referring
to the pinned tag) to read: "This downloads the example .env file for the
v5.0.0 release tag." Locate the markdown note containing the curl example and
the sentence "Will download the example .env file for the v5.0.0 tag." and
replace that sentence with the new wording; keep the existing code block
unchanged.


</details>

</blockquote></details>
<details>
<summary>src/content/docs/docs/guides/github-app-oauth.mdx-6-6 (1)</summary><blockquote>

`6-6`: _⚠️ Potential issue_ | _🟡 Minor_

**Internal link uses incorrect `.md` extension and should be extensionless.**

All other internal links throughout the documentation use extensionless paths (e.g., `/docs/reference/configuration`, `/docs/guides/nginx-proxy-manager`), which matches Astro/Starlight's routing structure. The link on line 6 should follow the same pattern.

<details>
<summary>Suggested fix</summary>

```diff
-Tinyauth supports GitHub Apps for authentication instead of OAuth Apps. GitHub Apps allow for more control over permissions and are slightly more complex to set up. For simpler setups, [OAuth Apps](/docs/guides/github-oauth.md) are recommended.
+Tinyauth supports GitHub Apps for authentication instead of OAuth Apps. GitHub Apps allow for more control over permissions and are slightly more complex to set up. For simpler setups, [OAuth Apps](/docs/guides/github-oauth) are recommended.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/content/docs/docs/guides/github-app-oauth.mdx` at line 6, Update the
internal link target for the GitHub OAuth guide to use the extensionless route:
replace the href "/docs/guides/github-oauth.md" with "/docs/guides/github-oauth"
in the markdown on line containing "Tinyauth supports GitHub Apps..." so it
matches the Astro/Starlight routing and other docs links.
src/content/docs/docs/community/kubernetes.mdx-98-123 (1)

98-123: ⚠️ Potential issue | 🟡 Minor

Use one hostname placeholder consistently across prose and YAML.

Line 98 uses my-host.domain.com, while Line 123 uses my-host.example.com. Keep one placeholder to avoid copy/paste mistakes.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/content/docs/docs/community/kubernetes.mdx` around lines 98 - 123,
Replace the inconsistent hostname placeholders so the prose and YAML use the
same example host; change either the prose `my-host.domain.com` or the YAML
`host: my-host.example.com` so both read the same (e.g., make the prose
reference `my-host.example.com` to match the `host` field and update any other
occurrences), ensuring the prose text that describes the ingress and the YAML
`host` value are identical.
src/content/docs/docs/community/kubernetes.mdx-10-10 (1)

10-10: ⚠️ Potential issue | 🟡 Minor

Use “Kubernetes-hosted” for compound adjective clarity.

Line 10 reads better and more correctly with a hyphenated form.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/content/docs/docs/community/kubernetes.mdx` at line 10, Replace the
phrase "Kubernetes hosted applications" with the hyphenated compound adjective
"Kubernetes-hosted applications" in the sentence that begins with "Kubernetes
hosted applications are commonly exposed..." so the doc uses the correct
compound-adjective form for clarity and grammatical correctness.
src/content/docs/docs/guides/runtipi.mdx-34-34 (1)

34-34: ⚠️ Potential issue | 🟡 Minor

Use "App Store" (two words) instead of "appstore" to match Runtipi's official documentation terminology.

Update lines 34 and 39:

  • Line 34: "official appstore" → "official App Store"
  • Line 39: "appstore tab" → "App Store tab"

Runtipi's official documentation consistently uses "App Store" (two words) for this feature.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/content/docs/docs/guides/runtipi.mdx` at line 34, Replace the lowercase
single-word "appstore" instances in the document with the two-word, capitalized
term "App Store": change the phrase "official appstore" to "official App Store"
and change "appstore tab" to "App Store tab" (search for the exact strings
"official appstore" and "appstore tab" in
src/content/docs/docs/guides/runtipi.mdx and update them accordingly).
src/pages/index.astro-25-25 (1)

25-25: ⚠️ Potential issue | 🟡 Minor

Guard custom element registration to avoid duplicate-definition errors.

Line 25 calls customElements.define unconditionally. If this script is evaluated again, it can throw and break page behavior.

Suggested fix
-    customElements.define("instances-count", InstancesCount);
+    if (!customElements.get("instances-count")) {
+        customElements.define("instances-count", InstancesCount);
+    }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/pages/index.astro` at line 25, The code unconditionally calls
customElements.define("instances-count", InstancesCount) which can throw if the
element is already registered; update the registration to first check
customElements.get("instances-count") and only call customElements.define when
that returns undefined (i.e., guard the define with a lookup), referencing the
existing InstancesCount class/constructor and the "instances-count" tag to avoid
duplicate-definition errors.
src/content/docs/docs/reference/configuration.mdx-54-55 (1)

54-55: ⚠️ Potential issue | 🟡 Minor

Differentiate OAUTH_WHITELIST vs OAUTH_GROUPS descriptions.

Both rows currently read like group filters, which makes their intent overlap. Please make the whitelist row explicitly describe whitelist entries (not groups), and keep groups in the groups row.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/content/docs/docs/reference/configuration.mdx` around lines 54 - 55,
Update the two table descriptions so they are distinct: change the
`TINYAUTH_APPS_[NAME]_OAUTH_WHITELIST` / `--apps.[name].oauth.whitelist`
description to explicitly say it is a comma-separated list of allowed OAuth
identities (e.g., usernames, emails, or specific account identifiers) that are
permitted access, and leave the `TINYAUTH_APPS_[NAME]_OAUTH_GROUPS` /
`--apps.[name].oauth.groups` description as a comma-separated list of required
OAuth groups (i.e., group names) that a user must belong to; modify those two
description cells in the table accordingly.
src/content/docs/docs/breaking-updates/4-to-5.mdx-20-24 (1)

20-24: ⚠️ Potential issue | 🟡 Minor

Clarify that top-level keys/flags are exceptions to the nested format.

The current wording reads as universal (TINYAUTH_<SECTION>_<KEY> / --section.key=value), but v5 docs also use top-level forms like TINYAUTH_APPURL and --appurl. Please document both shapes explicitly to prevent incorrect migrations.

Suggested wording update
-Environment variables, now, follow the following format:
+Environment variables generally follow the format below for nested settings:

 TINYAUTH_<SECTION>_<KEY>=<VALUE>
+
+For top-level settings, use:
+TINYAUTH_<KEY>=<VALUE>
-CLI flags follow the following format:
+CLI flags generally follow the format below for nested settings:

 --section.key=value
+
+For top-level settings, use:
+--key=value

Also applies to: 30-34

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/content/docs/docs/breaking-updates/4-to-5.mdx` around lines 20 - 24,
Clarify that environment variables and CLI flags can be either nested or
top-level: keep the existing nested format example (`TINYAUTH_<SECTION>_<KEY>`
and `--section.key=value`) but add an explicit exception sentence and examples
for top-level keys such as `TINYAUTH_APPURL` and `--appurl` so readers know both
shapes are supported; update the passages that mention
`TINYAUTH_<SECTION>_<KEY>` / `--section.key=value` (and the similar block later)
to show both forms and a brief note on when to use each.
src/content/docs/docs/reference/changelog.mdx-49-49 (1)

49-49: ⚠️ Potential issue | 🟡 Minor

Fix typo in changelog entry (paerserparser).

Small text bug in a user-facing release note.

Suggested fix
-- Simplify user parsing logic since we can offload things to paerser
+- Simplify user parsing logic since we can offload things to parser
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/content/docs/docs/reference/changelog.mdx` at line 49, In the changelog
entry inside src/content/docs/docs/reference/changelog.mdx that currently reads
"Simplify user parsing logic since we can offload things to paerser", fix the
typo by replacing "paerser" with "parser" so the line reads "Simplify user
parsing logic since we can offload things to parser".
src/content/docs/docs/reference/headers.mdx-29-34 (1)

29-34: ⚠️ Potential issue | 🟡 Minor

Resolve contradiction in Remote-Groups availability text.

Line 29 says groups may come from OIDC or LDAP, but the caution says groups are only available for OIDC providers. Please align these statements.

Suggested fix
-:::caution
-  Remote groups are only available for OIDC providers that support the `groups`
-  claim.
-:::
+:::caution
+  For OIDC providers, remote groups are only available when the `groups` claim
+  is present. LDAP-backed groups are handled via LDAP configuration.
+:::
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/content/docs/docs/reference/headers.mdx` around lines 29 - 34, The
"Remote-Groups" description and the caution contradict each other: update the
paragraph and caution so they consistently state that groups can come from both
OIDC and LDAP but with provider-specific constraints; e.g., keep the main text
saying groups are retrieved from the OIDC `groups` claim or from LDAP, and
change the caution block to say "Remote groups are available from LDAP and from
OIDC providers that support the `groups` claim" (or similar), referencing the
"Remote-Groups" header and the existing caution block to locate the text to
edit.
src/content/docs/docs/reference/configuration.mdx-8-11 (1)

8-11: ⚠️ Potential issue | 🟡 Minor

Clarify file-based option naming in the intro note.

The note says FILE_ equivalent, while the table primarily uses ...FILE suffix naming. Rewording this will reduce ambiguity.

Suggested wording update
-Configuration options with a `FILE_` equivalent (e.g., `USERS` and
-`USERS_FILE`) allow the `FILE_` environment variable or CLI flag to be used as
-an alternative.
+Configuration options with file-based variants (e.g., `...USERS` and
+`...USERSFILE`) allow using the file variant instead of inline secret values.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/content/docs/docs/reference/configuration.mdx` around lines 8 - 11,
Update the intro note to clarify the naming convention by replacing the
ambiguous "FILE_" wording with a clear reference to the `_FILE` suffix (for
example, `USERS` and `USERS_FILE`) so it matches the table's `...FILE` suffix
usage; edit the note that currently mentions `FILE_` to explicitly say the
`_FILE` suffix (or "…_FILE") is an alternative environment variable/CLI flag
form.
src/content/docs/docs/guides/oidc.mdx-105-105 (1)

105-105: ⚠️ Potential issue | 🟡 Minor

Clarify the client-name constraint wording.

Line 105 is internally inconsistent: “alphanumeric” excludes hyphens. Reword to avoid user misconfiguration.

Suggested wording fix
-The name of the client must be unique and alphanumeric; hyphens are allowed.
+The client name must be unique and contain only letters, numbers, and hyphens.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/content/docs/docs/guides/oidc.mdx` at line 105, Update the ambiguous
sentence "The name of the client must be unique and alphanumeric; hyphens are
allowed." in src/content/docs/docs/guides/oidc.mdx (the client-name constraint
sentence) to a clear, consistent phrasing such as: "The client name must be
unique and may contain letters, digits, and hyphens (e.g., ASCII letters and
numbers and '-' are allowed)." Ensure the revised wording explicitly lists
allowed characters and removes the contradictory use of "alphanumeric" followed
by "hyphens are allowed."
🧹 Nitpick comments (8)
src/content/docs/docs/community/zitadel-oauth.mdx (2)

59-61: Extra blank line.

There's a redundant blank line between the two admonitions (lines 59-60). Consider removing one for cleaner formatting.

📝 Suggested fix
 :::note
     Zitadel should be accessed using HTTPS and a trusted certificate. In case this is not possible (e.g. self-signed certificates), you will need to use `TINYAUTH_OAUTH_PROVIDERS_ZITADEL_INSECURE=true` in order for Tinyauth to skip the certificate check.
 :::
 
-
 :::caution
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/content/docs/docs/community/zitadel-oauth.mdx` around lines 59 - 61,
Remove the redundant blank line between the two admonition blocks (the
consecutive ":::caution" admonitions) so the admonitions are directly adjacent;
locate the second ":::caution" in the docs/community/zitadel-oauth.mdx content
and delete the extra empty line separating the two admonitions to restore clean
formatting.

56-71: Inconsistent indentation in admonitions.

The admonition content has inconsistent indentation: line 57 uses 4 spaces while lines 62-65 and 69-70 use 2 spaces. Starlight admonitions don't require indentation for the content. Consider removing the leading spaces for consistency and to avoid potential rendering issues.

📝 Suggested fix
 :::note
-    Zitadel should be accessed using HTTPS and a trusted certificate. In case this is not possible (e.g. self-signed certificates), you will need to use `TINYAUTH_OAUTH_PROVIDERS_ZITADEL_INSECURE=true` in order for Tinyauth to skip the certificate check.
+Zitadel should be accessed using HTTPS and a trusted certificate. In case this is not possible (e.g. self-signed certificates), you will need to use `TINYAUTH_OAUTH_PROVIDERS_ZITADEL_INSECURE=true` in order for Tinyauth to skip the certificate check.
 :::
 
 
 :::caution
-  OAuth alone does not guarantee security. By default, any Zitadel account can
-  log in as a normal user. To restrict access, use the `TINYAUTH_OAUTH_WHITELIST`
-  environment variable to allow specific email addresses. Refer to the
-  [configuration](/docs/reference/configuration) page for details.
+OAuth alone does not guarantee security. By default, any Zitadel account can
+log in as a normal user. To restrict access, use the `TINYAUTH_OAUTH_WHITELIST`
+environment variable to allow specific email addresses. Refer to the
+[configuration](/docs/reference/configuration) page for details.
 :::
 
 :::note
-  With OAuth enabled, the `TINYAUTH_AUTH_USERS` or `TINYAUTH_AUTH_USERSFILE` environment variable can be
-  removed to allow login exclusively through the OAuth provider.
+With OAuth enabled, the `TINYAUTH_AUTH_USERS` or `TINYAUTH_AUTH_USERSFILE` environment variable can be
+removed to allow login exclusively through the OAuth provider.
 :::
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/content/docs/docs/community/zitadel-oauth.mdx` around lines 56 - 71, The
admonitions using the :::note and :::caution blocks have inconsistent leading
spaces before their content; update each block (the lines following the :::note
and :::caution markers) to remove the extra leading spaces so the content is
flush with the admonition marker (no indentation) — e.g., fix the content under
the :::note and :::caution blocks so they start at column 0, leaving the
:::note/:::caution markers unchanged to ensure Starlight renders them
consistently.
src/styles/theme.css (1)

1-8: Consider merging duplicate :root declarations.

The two :root blocks (lines 1-3 and 5-8) can be combined into a single block for cleaner organization.

♻️ Suggested consolidation
 :root {
     --sl-hue-base: 140;
-}
-
-:root {
     --sl-color-accent: `#fafafa`;
     --sl-color-accent-high: `#f5f5f5`;
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/styles/theme.css` around lines 1 - 8, Combine the two duplicate :root
blocks into a single :root declaration that contains all CSS custom properties
(include --sl-hue-base, --sl-color-accent, and --sl-color-accent-high together)
and remove the redundant :root block; ensure you preserve the exact variable
names and values from the existing declarations so selectors using those
variables continue to work.
src/styles/home.css (1)

97-99: Consider using Starlight's CSS variables for theme consistency.

The hardcoded #3b82f6 won't adapt if the site's accent color or theme changes. Starlight provides accent color variables that would maintain consistency.

Proposed fix
 .link-button-primary {
-    background-color: `#3b82f6`;
+    background-color: var(--sl-color-accent);
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/styles/home.css` around lines 97 - 99, Replace the hardcoded color in the
.link-button-primary rule with Starlight's accent color variable(s): update the
background-color declaration in the .link-button-primary selector to use the
project's provided CSS variable (e.g., var(--accent) or the Starlight
equivalent) so the button follows theme/accent changes; ensure any hover/focus
states also reference the same variable for consistency.
src/content/docs/docs/guides/nginx-proxy-manager.mdx (2)

45-45: Clarify the “Docker labels” wording for Nginx Proxy Manager.

Line 45 implies labels are part of this flow, but this guide config is primarily managed through the Nginx Proxy Manager UI plus Tinyauth env vars.

Suggested wording
-OAuth and access controls can be configured using Docker labels and environment variables. All other configuration is managed through the Nginx Proxy Manager UI.
+OAuth and access controls are configured via Tinyauth environment variables, while host/proxy settings are managed through the Nginx Proxy Manager UI.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/content/docs/docs/guides/nginx-proxy-manager.mdx` at line 45, The
sentence "OAuth and access controls can be configured using Docker labels and
environment variables. All other configuration is managed through the Nginx
Proxy Manager UI." is misleading; update it to clarify that the primary
configuration is done via the Nginx Proxy Manager UI and that Docker labels are
only used for container metadata/automations while Tinyauth uses environment
variables—replace that sentence in
src/content/docs/docs/guides/nginx-proxy-manager.mdx (the line containing the
quoted text) with wording that explicitly states: primary config via the UI,
environment variables (e.g., Tinyauth) control access, and Docker labels are
ancillary/container-level metadata or automation hooks only.

29-30: Pin the traefik/whoami image to a specific version tag instead of latest.

Using :latest makes the guide non-reproducible over time. Docker best practices recommend pinning explicit version tags (e.g., v1.11) in documentation examples. The traefik/whoami image has stable versions available (v1.11 and v1.11.0). Note that other services in this file already use pinned tags (nginx-proxy-manager:2, tinyauth:v5), so this aligns the example with the established pattern.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/content/docs/docs/guides/nginx-proxy-manager.mdx` around lines 29 - 30,
Update the whoami service image to pin a specific version instead of using
`:latest`: locate the `whoami` service definition (the `whoami:` block) and
change the image value `traefik/whoami:latest` to a concrete tag such as
`traefik/whoami:v1.11` (or `v1.11.0`) so the example is reproducible and
consistent with the other pinned images (`nginx-proxy-manager:2`,
`tinyauth:v5`).
src/content/docs/docs/guides/oidc.mdx (1)

20-20: Prefer local hosting for the protocol image.

Line 20 hotlinks a third-party image URL. This creates a runtime dependency and privacy/reliability risk for docs rendering. Store the asset in-repo and reference it with a local path.

Suggested change
-![OpenID Connect Protocol Suite](https://openid.net/wp-content/uploads/2023/06/OpenIDConnect-Map-December2023.png)
+![OpenID Connect Protocol Suite](/images/oidc/openid-connect-protocol-suite.png)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/content/docs/docs/guides/oidc.mdx` at line 20, Replace the hotlinked
image reference "![OpenID Connect Protocol
Suite](https://openid.net/wp-content/uploads/2023/06/OpenIDConnect-Map-December2023.png)"
with a locally hosted asset: add the image file to the repo's docs assets (e.g.,
assets/images or docs/static) and update the markdown in
src/content/docs/docs/guides/oidc.mdx to reference the new relative path for the
same alt text; ensure the image is committed to the repo so the docs build does
not depend on the external URL.
package.json (1)

2-4: Consider restoring "private": true for the docs package.

Unless npm publishing is intentional, adding "private": true prevents accidental registry publish.

Suggested change
 {
   "name": "tinyauth-docs-astro",
+  "private": true,
   "type": "module",
   "version": "0.0.1",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@package.json` around lines 2 - 4, Add the "private": true field to the
package.json metadata to prevent accidental npm publishes; modify the package
manifest (the JSON object containing "name": "tinyauth-docs-astro", "type":
"module", "version": "0.0.1") by inserting "private": true at the top-level so
the package is treated as private by npm.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.gitignore:
- Around line 16-18: Update the .gitignore entries for environment files to
cover common local and environment-specific variants so secrets aren't
committed: add patterns like .env.local, .env.development, .env.test,
.env.*.local (which covers .env.development.local, .env.test.local,
.env.production.local), and consider a catch-all .env.* or explicit entries for
.env.production and .env.* as needed to ensure all variants (e.g., .env.local,
.env.development.local, .env.test) are ignored.

In `@package.json`:
- Around line 21-23: The package.json currently pins the Node engine exactly via
the "engines" -> "node" value ("v25.5.0"), which is brittle; update that "node"
engine entry to use a semver range instead (for example the upstream-supported
range "^18.17.1 || ^20.3.0 || >=22.0.0" or the simpler ">=20.3.0 <26") so CI and
contributors aren’t blocked by an exact patch-level pin and installs respect
compatible Node versions.

In `@src/content/docs/docs/community/kubernetes.mdx`:
- Around line 60-63: The Deployment currently embeds credentials in the
TINYAUTH_AUTH_USERS env var (and an example user/password), so remove that
inline value and create a Kubernetes Secret (e.g., name tinyauth-auth-users,
type Opaque, stringData with key users containing "<username>:<bcrypt-hash>");
then update the Deployment to source the users data from the Secret (use env
valueFrom secretKeyRef or envFrom as appropriate) while keeping TINYAUTH_APPURL
as an env value; ensure references match the Secret name and the key "users" so
the application reads credentials from the secret instead of the inline
TINYAUTH_AUTH_USERS value.
- Around line 203-213: The AuthorizationPolicy named tinyauth-policy currently
uses namespace: my-namespace but references the Gateway my-public-gateway via
targetRefs (kind: Gateway), which must live in the same namespace; update the
AuthorizationPolicy's metadata.namespace to the Gateway's namespace (ingress) or
move my-public-gateway into my-namespace so the AuthorizationPolicy and the
referenced Gateway share the same namespace, ensuring targetRefs: - kind:
Gateway name: my-public-gateway resolves correctly.

In `@src/content/docs/docs/guides/access-controls.mdx`:
- Line 44: The socket proxy label example contains a trailing apostrophe in the
path value: `socket-proxy.allow.head: /_ping'`; remove the stray apostrophe so
the value reads `/_ping` to ensure the example copies correctly and the
configuration is valid (edit the `socket-proxy.allow.head` example to drop the
trailing single quote).

In `@src/content/docs/docs/guides/nginx-proxy-manager.mdx`:
- Around line 130-132: The Nginx location block named "location
`@tinyauth_unauthorized`" has a return directive missing its terminating
semicolon; update the return line inside the location `@tinyauth_unauthorized`
block (the `return` directive) to append a trailing `;` so the directive is
properly terminated and the Nginx config will parse.

In `@src/content/docs/docs/guides/pocket-id.mdx`:
- Around line 94-100: The documentation contains a broken anchor link: update
the link "/docs/guides/access-controls#label-discovery" in
src/content/docs/docs/guides/pocket-id.mdx to point to the actual heading anchor
(change to "/docs/guides/access-controls#access-controls-discovery") or the
correct target if a different section was intended; locate the paragraph
containing the `tinyauth.apps.[app].config.domain` text and fix the anchor
portion of the link so it matches the "## Access Controls Discovery" heading
anchor.

In `@src/content/docs/docs/reference/cli.mdx`:
- Around line 37-41: The Docker example under the "Docker" TabItem currently
runs an ephemeral container with the default healthcheck URL (127.0.0.1:3000)
which checks localhost inside the container, not the host/sibling Tinyauth
service; update the docs by replacing that example with one of these fixes: (1)
show docker exec against a running Tinyauth container (i.e., run the healthcheck
binary inside the existing container), (2) demonstrate passing an explicit
external URL argument to the healthcheck command (so the example uses the
host/sibling container address), or (3) add a clear note in the "Docker" TabItem
that the default healthcheck URL only works when the service and checker share
the same network namespace; reference the "Docker" TabItem and the healthcheck
invocation in the snippet so users know which example to change.

In `@src/lib/4-to-5-config-migrator.ts`:
- Around line 93-103: The parser currently checks flag.includes(" ") before
handling "=" so inputs like "--app-title=My App" get split on the space and
produce key="--app-title=My" incorrectly; change the branch order and split
logic to prefer "=" first: detect if flag contains "=" and split on the first
"=" (use split and join the rest as the value) to produce key and value
correctly, otherwise fall back to splitting on the first space; reference the
variables "flag", "flagSplit", "res", and the surrounding logic in
src/lib/4-to-5-config-migrator.ts when making this change.

In `@src/lib/get-instances.ts`:
- Around line 8-10: The current fetch code (calling apiUrl +
"/v1/instances/all") blindly parses and returns the response as InstancesRes;
update the logic to first check res.ok and, if false, read and include the
response body/text in an error you throw (include status and statusText) so
callers get meaningful failures, then parse JSON into data and validate its
shape before returning (e.g., ensure expected properties/arrays exist on the
parsed object that match InstancesRes); reference the existing const res and
const data variables and the InstancesRes type when adding the checks and
throwing descriptive errors.

In `@src/pages/index.astro`:
- Around line 12-22: The updateData function awaits getInstances() without error
handling; wrap the async call and the subsequent CountUp creation/start in a
try/catch inside updateData (referencing updateData, getInstances, CountUp and
the "instances-count" element) and on catch log the error (console.error) and
gracefully degrade the widget (e.g., instantiate CountUp with 0 or display an
error state) so unhandled promise rejections are prevented and the UI remains
consistent.

---

Minor comments:
In `@src/content/docs/docs/breaking-updates/3-to-4.mdx`:
- Around line 150-154: Update the note text to use the hyphenated compound
modifier: replace the phrase "Container name based label discovery is no longer
supported." with "Container-name-based label discovery is no longer supported."
in the block containing the example `myapp.example.com` and the label
`tinyauth.apps.myapp.foo: bar` so the grammar and readability are corrected.

In `@src/content/docs/docs/breaking-updates/4-to-5.mdx`:
- Around line 20-24: Clarify that environment variables and CLI flags can be
either nested or top-level: keep the existing nested format example
(`TINYAUTH_<SECTION>_<KEY>` and `--section.key=value`) but add an explicit
exception sentence and examples for top-level keys such as `TINYAUTH_APPURL` and
`--appurl` so readers know both shapes are supported; update the passages that
mention `TINYAUTH_<SECTION>_<KEY>` / `--section.key=value` (and the similar
block later) to show both forms and a brief note on when to use each.

In `@src/content/docs/docs/community/kubernetes.mdx`:
- Around line 98-123: Replace the inconsistent hostname placeholders so the
prose and YAML use the same example host; change either the prose
`my-host.domain.com` or the YAML `host: my-host.example.com` so both read the
same (e.g., make the prose reference `my-host.example.com` to match the `host`
field and update any other occurrences), ensuring the prose text that describes
the ingress and the YAML `host` value are identical.
- Line 10: Replace the phrase "Kubernetes hosted applications" with the
hyphenated compound adjective "Kubernetes-hosted applications" in the sentence
that begins with "Kubernetes hosted applications are commonly exposed..." so the
doc uses the correct compound-adjective form for clarity and grammatical
correctness.

In `@src/content/docs/docs/getting-started.mdx`:
- Around line 94-95: Replace the inconsistent example for TINYAUTH_AUTH_USERS
with a single, copy-safe example that follows the documented
username:hash[:totp] schema (e.g., using a bcrypt-style hash); update both
occurrences (the snippet containing TINYAUTH_AUTH_USERS at the shown spot and
the other instance around lines 137–138) so they use the same example format and
include the variable name TINYAUTH_AUTH_USERS for clarity.

In `@src/content/docs/docs/guides/github-app-oauth.mdx`:
- Line 6: Update the internal link target for the GitHub OAuth guide to use the
extensionless route: replace the href "/docs/guides/github-oauth.md" with
"/docs/guides/github-oauth" in the markdown on line containing "Tinyauth
supports GitHub Apps..." so it matches the Astro/Starlight routing and other
docs links.

In `@src/content/docs/docs/guides/ldap.mdx`:
- Line 68: Fix the malformed LDAP filter inline code by removing the extra
leading double-quote before the filter snippet
`"(&(objectclass=groupOfUniqueNames)(uniquemember=%s))` so it reads
`(&(objectclass=groupOfUniqueNames)(uniquemember=%s))`; update the inline code
in src/content/docs/docs/guides/ldap.mdx where the filter string appears to
ensure the backticks wrap only the filter text and no stray quote characters
remain.

In `@src/content/docs/docs/guides/oidc.mdx`:
- Line 105: Update the ambiguous sentence "The name of the client must be unique
and alphanumeric; hyphens are allowed." in src/content/docs/docs/guides/oidc.mdx
(the client-name constraint sentence) to a clear, consistent phrasing such as:
"The client name must be unique and may contain letters, digits, and hyphens
(e.g., ASCII letters and numbers and '-' are allowed)." Ensure the revised
wording explicitly lists allowed characters and removes the contradictory use of
"alphanumeric" followed by "hyphens are allowed."

In `@src/content/docs/docs/guides/pocket-id.mdx`:
- Around line 53-60: Remove the extra leading spaces inside both admonition
blocks so the content lines align directly under the ":::note" markers;
specifically, unindent the lines containing the
TINYAUTH_OAUTH_PROVIDERS_POCKETID_INSECURE description and the
TINYAUTH_OAUTH_AUTOREDIRECT instruction so they match the other admonition line
spacing, ensuring the ":::note" blocks render consistently in Starlight/Astro.

In `@src/content/docs/docs/guides/runtipi.mdx`:
- Line 34: Replace the lowercase single-word "appstore" instances in the
document with the two-word, capitalized term "App Store": change the phrase
"official appstore" to "official App Store" and change "appstore tab" to "App
Store tab" (search for the exact strings "official appstore" and "appstore tab"
in src/content/docs/docs/guides/runtipi.mdx and update them accordingly).

In `@src/content/docs/docs/guides/using-the-binary.mdx`:
- Around line 24-32: Replace the phrase "latest stable version" with "a stable
released tag" and update the explanatory sentence after the curl example (the
paragraph referring to the pinned tag) to read: "This downloads the example
`.env` file for the v5.0.0 release tag." Locate the markdown note containing the
curl example and the sentence "Will download the example `.env` file for the
`v5.0.0` tag." and replace that sentence with the new wording; keep the existing
code block unchanged.

In `@src/content/docs/docs/reference/changelog.mdx`:
- Line 49: In the changelog entry inside
src/content/docs/docs/reference/changelog.mdx that currently reads "Simplify
user parsing logic since we can offload things to paerser", fix the typo by
replacing "paerser" with "parser" so the line reads "Simplify user parsing logic
since we can offload things to parser".

In `@src/content/docs/docs/reference/configuration.mdx`:
- Around line 54-55: Update the two table descriptions so they are distinct:
change the `TINYAUTH_APPS_[NAME]_OAUTH_WHITELIST` /
`--apps.[name].oauth.whitelist` description to explicitly say it is a
comma-separated list of allowed OAuth identities (e.g., usernames, emails, or
specific account identifiers) that are permitted access, and leave the
`TINYAUTH_APPS_[NAME]_OAUTH_GROUPS` / `--apps.[name].oauth.groups` description
as a comma-separated list of required OAuth groups (i.e., group names) that a
user must belong to; modify those two description cells in the table
accordingly.
- Around line 8-11: Update the intro note to clarify the naming convention by
replacing the ambiguous "FILE_" wording with a clear reference to the `_FILE`
suffix (for example, `USERS` and `USERS_FILE`) so it matches the table's
`...FILE` suffix usage; edit the note that currently mentions `FILE_` to
explicitly say the `_FILE` suffix (or "…_FILE") is an alternative environment
variable/CLI flag form.

In `@src/content/docs/docs/reference/headers.mdx`:
- Around line 29-34: The "Remote-Groups" description and the caution contradict
each other: update the paragraph and caution so they consistently state that
groups can come from both OIDC and LDAP but with provider-specific constraints;
e.g., keep the main text saying groups are retrieved from the OIDC `groups`
claim or from LDAP, and change the caution block to say "Remote groups are
available from LDAP and from OIDC providers that support the `groups` claim" (or
similar), referencing the "Remote-Groups" header and the existing caution block
to locate the text to edit.

In `@src/content/docs/docs/reference/labels.mdx`:
- Line 42: Update the description for the label
`tinyauth.apps.[app].ldap.groups` to use the hyphenated compound adjective
"comma-separated" instead of "comma separated"; locate the table row containing
the `tinyauth.apps.[app].ldap.groups` key in labels.mdx and replace the phrase
so the description reads "A comma-separated list of LDAP groups required by a
user to access the app."

In `@src/pages/index.astro`:
- Line 25: The code unconditionally calls
customElements.define("instances-count", InstancesCount) which can throw if the
element is already registered; update the registration to first check
customElements.get("instances-count") and only call customElements.define when
that returns undefined (i.e., guard the define with a lookup), referencing the
existing InstancesCount class/constructor and the "instances-count" tag to avoid
duplicate-definition errors.

In `@src/styles/home.css`:
- Around line 8-10: The current selector "&:not(.content-panel:has(.sl-banner))
.content-panel:first-of-type" is wrong because it tests whether the parent
itself has the .content-panel class; change it to test whether the parent has a
.sl-banner and hide the first panel only when there's no banner. Replace that
selector with "&:not(:has(.sl-banner)) .content-panel:first-of-type { display:
none; }" so the rule hides the first .content-panel only when the parent does
not contain .sl-banner.

In `@src/styles/theme.css`:
- Around line 43-48: The CSS for .sl-markdown-content img uses border-width: 2px
followed by border: 1px solid which overrides it, so change the declarations to
a single consolidated border rule or keep width/style/color separate; for
example update the .sl-markdown-content img rule to use border: 2px solid
var(--sl-color-gray-5) (or remove the shorthand and keep border-width: 2px plus
border-style: solid and border-color: var(--sl-color-gray-5)) so the intended
2px border is applied.

---

Nitpick comments:
In `@package.json`:
- Around line 2-4: Add the "private": true field to the package.json metadata to
prevent accidental npm publishes; modify the package manifest (the JSON object
containing "name": "tinyauth-docs-astro", "type": "module", "version": "0.0.1")
by inserting "private": true at the top-level so the package is treated as
private by npm.

In `@src/content/docs/docs/community/zitadel-oauth.mdx`:
- Around line 59-61: Remove the redundant blank line between the two admonition
blocks (the consecutive ":::caution" admonitions) so the admonitions are
directly adjacent; locate the second ":::caution" in the
docs/community/zitadel-oauth.mdx content and delete the extra empty line
separating the two admonitions to restore clean formatting.
- Around line 56-71: The admonitions using the :::note and :::caution blocks
have inconsistent leading spaces before their content; update each block (the
lines following the :::note and :::caution markers) to remove the extra leading
spaces so the content is flush with the admonition marker (no indentation) —
e.g., fix the content under the :::note and :::caution blocks so they start at
column 0, leaving the :::note/:::caution markers unchanged to ensure Starlight
renders them consistently.

In `@src/content/docs/docs/guides/nginx-proxy-manager.mdx`:
- Line 45: The sentence "OAuth and access controls can be configured using
Docker labels and environment variables. All other configuration is managed
through the Nginx Proxy Manager UI." is misleading; update it to clarify that
the primary configuration is done via the Nginx Proxy Manager UI and that Docker
labels are only used for container metadata/automations while Tinyauth uses
environment variables—replace that sentence in
src/content/docs/docs/guides/nginx-proxy-manager.mdx (the line containing the
quoted text) with wording that explicitly states: primary config via the UI,
environment variables (e.g., Tinyauth) control access, and Docker labels are
ancillary/container-level metadata or automation hooks only.
- Around line 29-30: Update the whoami service image to pin a specific version
instead of using `:latest`: locate the `whoami` service definition (the
`whoami:` block) and change the image value `traefik/whoami:latest` to a
concrete tag such as `traefik/whoami:v1.11` (or `v1.11.0`) so the example is
reproducible and consistent with the other pinned images
(`nginx-proxy-manager:2`, `tinyauth:v5`).

In `@src/content/docs/docs/guides/oidc.mdx`:
- Line 20: Replace the hotlinked image reference "![OpenID Connect Protocol
Suite](https://openid.net/wp-content/uploads/2023/06/OpenIDConnect-Map-December2023.png)"
with a locally hosted asset: add the image file to the repo's docs assets (e.g.,
assets/images or docs/static) and update the markdown in
src/content/docs/docs/guides/oidc.mdx to reference the new relative path for the
same alt text; ensure the image is committed to the repo so the docs build does
not depend on the external URL.

In `@src/styles/home.css`:
- Around line 97-99: Replace the hardcoded color in the .link-button-primary
rule with Starlight's accent color variable(s): update the background-color
declaration in the .link-button-primary selector to use the project's provided
CSS variable (e.g., var(--accent) or the Starlight equivalent) so the button
follows theme/accent changes; ensure any hover/focus states also reference the
same variable for consistency.

In `@src/styles/theme.css`:
- Around line 1-8: Combine the two duplicate :root blocks into a single :root
declaration that contains all CSS custom properties (include --sl-hue-base,
--sl-color-accent, and --sl-color-accent-high together) and remove the redundant
:root block; ensure you preserve the exact variable names and values from the
existing declarations so selectors using those variables continue to work.

Comment thread .gitignore
Comment thread package.json
Comment thread src/content/docs/docs/community/kubernetes.mdx
Comment thread src/content/docs/docs/community/kubernetes.mdx
Comment thread src/content/docs/docs/guides/access-controls.mdx Outdated
Comment thread src/content/docs/docs/guides/pocket-id.mdx
Comment thread src/content/docs/docs/reference/cli.mdx
Comment thread src/lib/4-to-5-config-migrator.ts Outdated
Comment thread src/lib/get-instances.ts
Comment thread src/pages/index.astro
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 18

♻️ Duplicate comments (7)
src/content/docs/docs/guides/nginx-proxy-manager.mdx (1)

130-132: ⚠️ Potential issue | 🟠 Major

Add the missing semicolon in the Nginx return example.

Line 131 is missing a terminating ;. This makes the sample config invalid and likely to fail parsing when copied.

Proposed fix
   location `@tinyauth_unauthorized` {
-    return 302 http://tinyauth.example.com/unauthorized?username=unavailable # Replace with your app URL
+    return 302 http://tinyauth.example.com/unauthorized?username=unavailable; # Replace with your app URL
   }
#!/bin/bash
# Verify this guide contains any Nginx `return` directives without a trailing semicolon.
# Expected: no matches after applying the fix.

TARGET="$(fd -t f '^nginx-proxy-manager\.mdx$' | head -n1)"
nl -ba "$TARGET" | sed -n '124,134p'
rg -nP '^\s*return\b(?!.*;)\s.*$' "$TARGET"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/content/docs/docs/guides/nginx-proxy-manager.mdx` around lines 130 - 132,
The Nginx example under the location block named "location
`@tinyauth_unauthorized`" has a malformed return directive missing a trailing
semicolon; edit the return line inside that block (the "return 302
http://tinyauth.example.com/unauthorized?username=unavailable" statement) and
add the terminating ";" so the directive becomes a valid Nginx return statement.
src/lib/get-instances.ts (1)

8-10: ⚠️ Potential issue | 🟠 Major

Handle non-OK responses and validate response shape before returning.

At Line 8–Line 10, the function still trusts status + payload shape and can fail at runtime on API errors or malformed JSON.

🛠️ Suggested hardening
 export const getInstances = async (): Promise<InstancesRes> => {
-  const res = await fetch(apiUrl + "/v1/instances/all");
-  const data = await res.json();
-  return data as InstancesRes;
+  const res = await fetch(`${apiUrl}/v1/instances/all`);
+  if (!res.ok) {
+    const body = await res.text().catch(() => "");
+    throw new Error(
+      `Failed to fetch instances (${res.status} ${res.statusText})${body ? `: ${body}` : ""}`,
+    );
+  }
+
+  const data: unknown = await res.json();
+  if (
+    typeof data !== "object" ||
+    data === null ||
+    typeof (data as { total?: unknown }).total !== "number"
+  ) {
+    throw new Error("Invalid instances response payload");
+  }
+
+  return { total: (data as { total: number }).total };
 };
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/get-instances.ts` around lines 8 - 10, The fetch result is assumed OK
and the JSON blindly cast to InstancesRes; wrap the fetch+res.json() in
try/catch, check res.ok and throw or return a clear error when status is not
2xx, and validate the parsed payload shape before casting (e.g., check expected
top-level fields or Array structure) so you don't return malformed data; update
the block referencing res, data and InstancesRes to perform these checks and
surface/throw a descriptive error on failure.
src/content/docs/docs/reference/cli.mdx (1)

37-41: ⚠️ Potential issue | 🟠 Major

Docker healthcheck examples still imply an incorrect localhost target.

docker run ... healthcheck with default 127.0.0.1:3000 checks the ephemeral checker container itself, not the target Tinyauth instance, so the guidance remains misleading.

📝 Suggested doc adjustment
 <TabItem label="Docker">
   ```sh
-  docker run -i -t --rm ghcr.io/steveiliop56/tinyauth:v5 healthcheck
+  docker run -i -t --rm ghcr.io/steveiliop56/tinyauth:v5 healthcheck http://tinyauth:3000
```
 :::note
-It is advised to not use the healthcheck command with the public URL of Tinyauth as it can result to connection issues. It is recommended to use the healthcheck command with the internal URL of Tinyauth (e.g., `http://127.0.0.1:3000`).
+When running healthcheck from an ephemeral Docker container, `127.0.0.1` points to that checker container. Use the target service/container address (e.g., `http://tinyauth:3000`) on the shared Docker network.
 :::

Also applies to: 50-50, 65-67

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/content/docs/docs/reference/cli.mdx` around lines 37 - 41, The Docker
healthcheck examples in the Tabs/TabItem "Docker" currently show `docker run ...
healthcheck` which checks the ephemeral checker container itself; update the
example commands used in the TabItem code blocks to pass the target Tinyauth URL
(e.g., append `http://tinyauth:3000` or an explicit host:port) so the container
checks the actual service, and apply the same fix to the other occurrences
referenced (the other TabItem code blocks around the later examples).
package.json (1)

21-23: ⚠️ Potential issue | 🟠 Major

Avoid exact Node engine pin; use a semver range.

At Line 22, "v25.5.0" is brittle and can block otherwise compatible environments. Please switch to a supported range.

🔧 Suggested change
   "engines": {
-    "node": "v25.5.0"
+    "node": ">=20.3.0 <26"
   }
#!/bin/bash
# Verify current engine pin and inspect registry engine metadata for Astro/Starlight
python - <<'PY'
import json, urllib.request, urllib.parse

with open("package.json", "r", encoding="utf-8") as f:
    pkg = json.load(f)

print("package.json engines.node =", pkg.get("engines", {}).get("node"))
deps = pkg.get("dependencies", {})
for name in ("astro", "@astrojs/starlight"):
    print(f"{name} declared range =", deps.get(name))
    url = f"https://registry.npmjs.org/{urllib.parse.quote(name)}"
    data = json.load(urllib.request.urlopen(url))
    latest = data["dist-tags"]["latest"]
    engines = data["versions"][latest].get("engines", {})
    print(f"{name} latest={latest}, engines.node={engines.get('node')}")
PY
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@package.json` around lines 21 - 23, Replace the exact engine pin "v25.5.0" in
package.json's "engines.node" with a semver range (e.g., ">=18" or a more
specific supported range) so environments are not brittle; update the "engines"
entry (the symbol to change: engines.node) to a range string, then verify
compatibility with your dependencies (astro / `@astrojs/starlight`) by inspecting
their published "engines.node" values (use the provided registry inspection
snippet or npm info) and adjust the range if needed.
src/pages/index.astro (1)

12-21: ⚠️ Potential issue | 🟠 Major

Handle async fetch failures in the counter update path.

The current flow can still fail with an unhandled rejection if instance loading errors out.

Suggested fix
         connectedCallback() {
             async function updateData() {
-                const instances = await getInstances();
-                const counter = new CountUp("instances-count", instances.total);
-                if (!counter.error) {
-                    counter.start();
-                } else {
-                    console.error(counter.error);
-                }
+                try {
+                    const instances = await getInstances();
+                    const counter = new CountUp("instances-count", instances.total);
+                    if (!counter.error) {
+                        counter.start();
+                    } else {
+                        console.error(counter.error);
+                    }
+                } catch (err) {
+                    console.error("Failed to load instances count", err);
+                }
             }
             updateData();
         }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/pages/index.astro` around lines 12 - 21, The updateData function can
throw an unhandled rejection when getInstances() fails; wrap the await
getInstances() call (inside updateData) in a try/catch (or attach a .catch) and
handle errors by logging them and skipping or providing a safe fallback count
before creating the CountUp instance (referencing updateData, getInstances,
CountUp, and instances.total), ensuring the counter code only runs when
instances and instances.total are valid.
.gitignore (1)

16-18: ⚠️ Potential issue | 🟠 Major

Expand env-file ignore coverage to prevent accidental secret commits.

Only ignoring .env and .env.production still leaves common variants trackable (for example .env.local, .env.development.local).

Suggested fix
 # environment variables
 .env
-.env.production
+.env.*
+!.env.example
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.gitignore around lines 16 - 18, Update the .gitignore entries for
environment files to cover common variants so secrets aren’t accidentally
committed: replace the two explicit ignores with a broader pattern that ignores
all .env variants (e.g. .env.* and .env.local/.env.*.local) while keeping any
explicit example files (like .env.example) tracked if you use them; modify the
.gitignore to include these broader patterns so functions that read .env (or
deploy scripts) aren’t at risk of committing sensitive files.
src/lib/4-to-5-config-migrator.ts (1)

93-103: ⚠️ Potential issue | 🔴 Critical

Fix CLI parser order for --key=value with spaces inputs.

Parsing still splits on spaces before =, which corrupts keys/values for valid flag forms.

Suggested fix
-    if (flag.includes(" ")) {
-      const flagSplit = flag.split(" ");
-      const key = flagSplit[0];
-      const value = flagSplit.slice(1).join(" ");
-      res[key] = value;
-      continue;
-    }
-    const flagSplit = flag.split("=");
-    const key = flagSplit[0];
-    const value = flagSplit.slice(1).join("=");
+    if (flag.includes("=")) {
+      const flagSplit = flag.split("=");
+      const key = flagSplit[0];
+      const value = flagSplit.slice(1).join("=");
+      res[key] = value;
+      continue;
+    }
+    const flagSplit = flag.split(" ");
+    const key = flagSplit[0];
+    const value = flagSplit.slice(1).join(" ");
     res[key] = value;
     continue;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/4-to-5-config-migrator.ts` around lines 93 - 103, The parser
currently checks for spaces before '=' which breaks flags like "--key=value with
spaces"; update the logic in the function handling `flag` so it first checks if
flag.includes("=") and parses key/value by splitting on "=" (joining remainder
with "="), otherwise if flag.includes(" ") split on the first space (join
remainder with " ")—assign results to `res[key]` as before (use the existing
`flagSplit`, `key`, `value`, and `res` identifiers).
🧹 Nitpick comments (7)
src/content/docs/docs/guides/runtipi.mdx (1)

39-39: Consider splitting this into step-by-step bullets.

Line 39 is very dense and mixes setup, domain constraints, and install completion in one paragraph. Converting to a short ordered list would make it easier to follow.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/content/docs/docs/guides/runtipi.mdx` at line 39, Break the dense
single-paragraph instruction (the paragraph starting "Navigate to the appstore
tab, select the Tinyauth app, and fill in the users, OAuth credentials...") into
a short ordered list of 4–6 concise steps: 1) open the Appstore tab and select
Tinyauth, 2) fill in users and OAuth credentials, 3) enable either the local
domain switch or the expose switch for domain accessibility and cookie handling,
4) choose the appropriate app URL (local or exposed) and ensure it uses HTTPS,
and 5) complete the installation; keep each bullet one sentence and preserve the
original guidance about cookie handling and HTTPS.
src/content/docs/docs/guides/pocket-id.mdx (1)

53-72: Inconsistent indentation in admonition blocks may cause rendering issues.

The content inside admonition blocks has varying indentation:

  • Line 54: 4-space indent
  • Line 58: 2-space indent
  • Lines 63-66, 70-71: No indent

In Markdown, 4-space indentation can trigger code block formatting. For consistent rendering in Starlight, remove the leading indentation from admonition content.

✨ Suggested fix
 :::note
-    Pocket ID should be accessed using HTTPS and a trusted certificate. In case this is not possible (e.g. self-signed certificates), you will need to use `TINYAUTH_OAUTH_PROVIDERS_POCKETID_INSECURE=true` in order for Tinyauth to skip the certificate check.
+Pocket ID should be accessed using HTTPS and a trusted certificate. In case this is not possible (e.g. self-signed certificates), you will need to use `TINYAUTH_OAUTH_PROVIDERS_POCKETID_INSECURE=true` in order for Tinyauth to skip the certificate check.
 :::

 :::note
-  Set the `TINYAUTH_OAUTH_AUTOREDIRECT` environment variable to `pocketid` to enable
+Set the `TINYAUTH_OAUTH_AUTOREDIRECT` environment variable to `pocketid` to enable
   automatic redirection to Pocket ID for Tinyauth-protected apps.
 :::
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/content/docs/docs/guides/pocket-id.mdx` around lines 53 - 72, Admonition
blocks (the :::note and :::caution sections) contain inconsistent leading spaces
causing some lines to render as code; remove all leading indentation inside each
admonition so the content lines start directly after the admonition marker
(e.g., adjust the blocks that begin with ":::note" and ":::caution" so their
inner lines have no leading spaces), ensuring each paragraph line under the :::
markers is left-aligned and not prefixed by 2–4 spaces to prevent accidental
code-block formatting.
src/content/docs/docs/getting-started.mdx (1)

91-95: Clarify this compose snippet as a service fragment.

The text says this is a docker-compose.yml configuration, but the snippet is shaped like a service block. That can cause copy-paste failures for readers.

✏️ Suggested wording tweak
-The following `docker-compose.yml` configuration deploys Tinyauth:
+Add the following service block to your `docker-compose.yml` to deploy Tinyauth:
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/content/docs/docs/getting-started.mdx` around lines 91 - 95, The snippet
shown (keys like image, restart, environment and env vars TINYAUTH_APPURL /
TINYAUTH_AUTH_USERS) is a docker-compose service fragment and should be labeled
as such; update the surrounding text to explicitly say this is a "service
fragment" (or add the top-level "services:" context) so readers know they must
place the block under a services: <service_name>: entry in their
docker-compose.yml rather than copy-pasting the indented keys at root.
src/content/docs/docs/reference/labels.mdx (1)

42-42: Minor grammar inconsistency flagged by static analysis.

Static analysis suggests "comma-separated" (hyphenated) is grammatically preferred. However, the entire table (lines 29-41) consistently uses "comma separated" without a hyphen. To maintain consistency within the file, either keep it as-is or update all occurrences together.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/content/docs/docs/reference/labels.mdx` at line 42, The table entry for
tinyauth.apps.[app].ldap.groups uses "comma separated" while static analysis
prefers "comma-separated" and the file currently has inconsistent usage; search
the document for all occurrences of "comma separated" and either (a) change this
single entry to match the existing "comma separated" wording for consistency, or
(b) update every occurrence (including the table rows describing labels and
descriptions such as the tinyauth.apps.[app].ldap.groups row) to the hyphenated
"comma-separated" so the file is consistent; pick one approach and apply the
replacement across the file.
src/content/docs/docs/guides/using-the-binary.mdx (1)

86-90: Consider using a fenced code block for the ExecStart example.

The inline code span wraps across lines, which is harder to scan/copy than a single fenced command snippet.

🧩 Optional readability tweak
 :::note
   For CLI flag-based setups, remove the `EnvironmentFile` line and append the
-  flags to the `ExecStart` line, e.g., `ExecStart=/some/path/tinyauth
-  --appurl=https://tinyauth.example.com`.
+  flags to the `ExecStart` line, e.g.:
+
+  ```ini
+  ExecStart=/some/path/tinyauth --appurl=https://tinyauth.example.com
+  ```
 :::
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/content/docs/docs/guides/using-the-binary.mdx` around lines 86 - 90,
Replace the multi-line inline code span in the note with a fenced code block so
the ExecStart example is easy to read and copy: remove the wrapped inline
backticks and instead insert a triple-backtick fenced block (optionally labeled
"ini") containing a single line with ExecStart=/some/path/tinyauth
--appurl=https://tinyauth.example.com; keep the surrounding prose about removing
EnvironmentFile and the note block intact.
src/content/docs/docs/breaking-updates/4-to-5-migrator.astro (1)

11-13: Prefer graceful failure over throwing a string in client code.

Hard-throwing here can break the page; return early with a logged error instead.

Suggested fix
-    if (!cfgForm || !cfgNew) {
-        throw "Form or new config element not found";
-    }
+    if (!cfgForm || !cfgNew) {
+        console.error("Form or new config element not found");
+        return;
+    }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/content/docs/docs/breaking-updates/4-to-5-migrator.astro` around lines 11
- 13, Replace the hard throw that uses a string when cfgForm or cfgNew is
missing with a graceful early return: detect the missing elements (cfgForm,
cfgNew), log a clear error (e.g., console.error or the page logger) including
which element is missing, and then return from the function to avoid breaking
the page instead of throwing; ensure any downstream code checks for those
elements before proceeding.
src/content/docs/docs/breaking-updates/4-to-5.mdx (1)

9-9: Use more neutral and concise wording in user-facing docs.

Line 9, Line 16, and Line 36 can be tightened for tone/clarity (for example, replacing “In order to…”, “was a mess”, and “quite powerful” phrasing).

Proposed wording tweak
- In order to follow this migration guide, you need to have Tinyauth v4 running. In case you are coming from Tinyauth v3, you need to migrate to v4 first. For migrating from Tinyauth v3, please refer to the [migration guide](/docs/breaking-updates/3-to-4).
+ To follow this migration guide, you need Tinyauth v4 running. If you are coming from Tinyauth v3, migrate to v4 first using the [migration guide](/docs/breaking-updates/3-to-4).

- In Tinyauth v4, the configuration was a mess - some options were not doing what they were supposed to do, they were hard to keep track of and generally not very intuitive. In Tinyauth v5, we've simplified the configuration format into one unified scheme across all configuration mediums.
+ In Tinyauth v4, configuration was inconsistent—some options did not behave as expected and were hard to track. In Tinyauth v5, the format is unified across all configuration methods.

- This format may seem unintuitive at first, but it's actually quite powerful and better than the previous delimiter-based format. It allows you to specify configuration options in a way that's easy to remember and easy to type.
+ This format may seem unintuitive at first, but it is powerful and clearer than the previous delimiter-based format. It lets you specify options in a way that is easier to remember and type.

Also applies to: 16-16, 36-36

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/content/docs/docs/breaking-updates/4-to-5.mdx` at line 9, Replace the
informal/wordy phrases in src/content/docs/docs/breaking-updates/4-to-5.mdx: at
Line 9 change "In order to follow this migration guide, you need to have
Tinyauth v4 running." to a shorter neutral form (e.g. "This migration guide
requires Tinyauth v4; migrate from v3 to v4 first and see
/docs/breaking-updates/3-to-4."), at Line 16 replace any "was a mess" phrasing
with neutral, specific language (e.g. "was complex" or "required significant
changes"), and at Line 36 replace "quite powerful" with a concise, objective
descriptor like "feature-rich" or "flexible"; keep tone professional and concise
across these sentences.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@astro.config.mjs`:
- Around line 10-14: The server configuration currently sets
server.allowedHosts: true which disables host allowlisting; update the astro
config by removing allowedHosts: true or replacing it with an explicit array of
trusted hostnames (e.g., server.allowedHosts: ["localhost",
"staging.example.com"]) so the server.allowedHosts setting is no longer a
boolean and only allows the specified hosts; locate the server object in
astro.config.mjs and change the allowedHosts entry accordingly.

In `@src/content/docs/docs/breaking-updates/3-to-4.mdx`:
- Around line 150-154: Update the wording in the note paragraph where it says
"Container name based label discovery is no longer supported" to use a
hyphenated compound adjective: change "name based" to "name-based" so the
sentence reads "Container name-based label discovery is no longer supported";
locate the phrase in the docs/breaking-updates 3-to-4 note block (the line
containing "Container name based label discovery") and apply this single-word
change for consistency and readability.
- Around line 90-94: Remove the extraneous comma after "provider IDs" in the
note paragraph starting with "Using `google` or `github` as provider IDs,
triggers automatic filling..." — change it to "Using `google` or `github` as
provider IDs triggers automatic filling..." so the sentence reads smoothly;
update the sentence in the block that contains the provider note (the paragraph
mentioning redirect URL and scopes) accordingly.

In `@src/content/docs/docs/community/kubernetes.mdx`:
- Line 10: Change the compound adjective "Kubernetes hosted applications" in the
sentence that begins with "Kubernetes hosted applications are commonly
exposed..." to "Kubernetes-hosted applications" (update the phrase in the doc
content to hyphenate the compound adjective).

In `@src/content/docs/docs/guides/access-controls.mdx`:
- Line 68: The sentence describing how Tinyauth matches configuration is missing
the word "variable" after "environment"; update the sentence that references the
example `TINYAUTH_APPS_APP1_FOO=bar` so it reads "environment variable" instead
of just "environment" to correct the grammar and clarify meaning.

In `@src/content/docs/docs/guides/github-app-oauth.mdx`:
- Line 6: The internal link currently points to "/docs/guides/github-oauth.md"
which will break in Astro/Starlight; update the link target used in the line
containing "OAuth Apps" to the extensionless path "/docs/guides/github-oauth" so
the internal navigation resolves correctly.

In `@src/content/docs/docs/guides/ldap.mdx`:
- Line 68: The LDAP filter string in the docs contains a stray leading
double-quote: the snippet
`"(&(objectclass=groupOfUniqueNames)(uniquemember=%s))` should not start with a
`"`. Edit the text that defines the LDAP filter (the string shown as
`"(&(objectclass=groupOfUniqueNames)(uniquemember=%s))`) and remove the leading
quote so the filter reads (&(objectclass=groupOfUniqueNames)(uniquemember=%s))
for correct LDAP syntax.

In `@src/content/docs/docs/guides/oidc.mdx`:
- Line 105: Update the ambiguous client-name constraint sentence ("The name of
the client must be unique and alphanumeric; hyphens are allowed.") to a clear,
unambiguous phrasing such as: "The client name must be unique and may contain
only letters, numbers, and hyphens." Ensure this replacement appears where that
sentence is defined in the OIDC guide (the client-name constraint line) so
readers understand both the uniqueness requirement and the exact allowed
characters.

In `@src/content/docs/docs/guides/runtipi.mdx`:
- Line 42: Remove the stray comma in the sentence that reads "Additional
customization options such as adding more OAuth providers, are available through
Runtipi's [user-config]..." — edit the text in
src/content/docs/docs/guides/runtipi.mdx so it reads "providers are available"
(i.e., delete the comma after "providers") to correct the grammar.
- Around line 31-34: Replace the awkward phrase "multiple appstores support was
added" with a clearer, grammatically correct sentence: e.g., "Starting with
Runtipi v4, support for multiple app stores was added, which may change the
container name." Also normalize casing to "app stores" (two words, lowercase) or
"App Stores" if you prefer title case, and keep the following sentence about the
forward auth URL intact (the URL
`http://tinyauth_migrated-tinyauth-1:3000/api/auth/traefik` should remain
as-is).

In `@src/content/docs/docs/guides/totp.mdx`:
- Line 50: Replace the awkward phrase "a user verified message" with a
hyphenated compound adjective; update the sentence that currently reads "a user
verified message is displayed" to "a user-verified message is displayed" (or
alternatively "a user verification message is displayed") to improve clarity and
correct grammar.

In `@src/content/docs/docs/guides/using-the-binary.mdx`:
- Around line 24-35: The text implies the sample tag v5.0.0 is the "latest
stable version"; update the copy around the curl example to explicitly state
that v5.0.0 is only an example tag and users should replace it with the current
release tag if they want the latest stable copy (refer to the sample URL and the
tag string `v5.0.0` and the `.env.example` resource), e.g. change the line that
currently says "Will download the example `.env` file for the `v5.0.0` tag." to
something like "This downloads the example `.env` file for tag `v5.0.0`. Replace
it with the current latest release tag when needed."

In `@src/content/docs/docs/reference/changelog.mdx`:
- Line 21: Update the release note strings to use compound-modifier hyphenation:
replace "Configurable component level logging [`@pushpinderbal`]" with
"Configurable component-level logging [`@pushpinderbal`]" and make the same
hyphenation change for the similar entry referenced on line 28 so both entries
read with "component-level" (or rephrase adverbially) for improved readability.
- Line 49: Fix the spelling mistake in the changelog entry that reads "Simplify
user parsing logic since we can offload things to paerser" by changing "paerser"
to "parser" so the line reads "Simplify user parsing logic since we can offload
things to parser"; update the text in the same changelog entry (the line
containing that sentence) to correct the typo.

In `@src/content/docs/docs/reference/configuration.mdx`:
- Line 85: Update the doc text to use correct brand casing and hyphenation:
change the occurrence of "github" in the sentence starting "Using `google` or
`github` as provider IDs..." to "GitHub" and update the phrase at the later
occurrence to read "JSON-formatted logs" (i.e., replace "JSON formatted logs" or
similar with the hyphenated "JSON-formatted logs") so both lines reflect the
requested casing and hyphenation.

In `@src/lib/4-to-5-config-migrator.ts`:
- Around line 67-69: The code currently checks line.startsWith("#") and
line.startsWith("--") on the raw line, so indented comment/flag lines slip
through; change the loop to trim the line once (e.g., const trimmed =
line.trim()) and use trimmed for the empty and prefix checks and for subsequent
key/value parsing (refer to the for (const line of lines) loop and its current
if condition) so indented comments are correctly skipped.

In `@src/styles/home.css`:
- Around line 8-10: The selector is negating the wrong element; instead of
checking the parent (&) for being a .content-panel that has .sl-banner, you
should target the content panel itself and hide the first one only when it does
NOT contain .sl-banner. Replace the current selector
(&:not(.content-panel:has(.sl-banner)) .content-panel:first-of-type) with a
selector that targets the panel like
.content-panel:not(:has(.sl-banner)):first-of-type (or, in nested form, &
.content-panel:not(:has(.sl-banner)):first-of-type) and keep the display: none
rule there.

In `@src/styles/theme.css`:
- Around line 45-47: The shorthand declaration `border: 1px solid;` overrides
the previously set `border-width: 2px;` causing a lint error; fix by removing or
replacing the `border` shorthand so the intended width is preserved — e.g.,
delete `border: 1px solid;` and explicitly set `border-style: solid;` (keep
`border-width: 2px;` and `border-color: var(--sl-color-gray-5);`) so that
`border-width`, `border-style`, and `border-color` are defined without shorthand
conflicts.

---

Duplicate comments:
In @.gitignore:
- Around line 16-18: Update the .gitignore entries for environment files to
cover common variants so secrets aren’t accidentally committed: replace the two
explicit ignores with a broader pattern that ignores all .env variants (e.g.
.env.* and .env.local/.env.*.local) while keeping any explicit example files
(like .env.example) tracked if you use them; modify the .gitignore to include
these broader patterns so functions that read .env (or deploy scripts) aren’t at
risk of committing sensitive files.

In `@package.json`:
- Around line 21-23: Replace the exact engine pin "v25.5.0" in package.json's
"engines.node" with a semver range (e.g., ">=18" or a more specific supported
range) so environments are not brittle; update the "engines" entry (the symbol
to change: engines.node) to a range string, then verify compatibility with your
dependencies (astro / `@astrojs/starlight`) by inspecting their published
"engines.node" values (use the provided registry inspection snippet or npm info)
and adjust the range if needed.

In `@src/content/docs/docs/guides/nginx-proxy-manager.mdx`:
- Around line 130-132: The Nginx example under the location block named
"location `@tinyauth_unauthorized`" has a malformed return directive missing a
trailing semicolon; edit the return line inside that block (the "return 302
http://tinyauth.example.com/unauthorized?username=unavailable" statement) and
add the terminating ";" so the directive becomes a valid Nginx return statement.

In `@src/content/docs/docs/reference/cli.mdx`:
- Around line 37-41: The Docker healthcheck examples in the Tabs/TabItem
"Docker" currently show `docker run ... healthcheck` which checks the ephemeral
checker container itself; update the example commands used in the TabItem code
blocks to pass the target Tinyauth URL (e.g., append `http://tinyauth:3000` or
an explicit host:port) so the container checks the actual service, and apply the
same fix to the other occurrences referenced (the other TabItem code blocks
around the later examples).

In `@src/lib/4-to-5-config-migrator.ts`:
- Around line 93-103: The parser currently checks for spaces before '=' which
breaks flags like "--key=value with spaces"; update the logic in the function
handling `flag` so it first checks if flag.includes("=") and parses key/value by
splitting on "=" (joining remainder with "="), otherwise if flag.includes(" ")
split on the first space (join remainder with " ")—assign results to `res[key]`
as before (use the existing `flagSplit`, `key`, `value`, and `res` identifiers).

In `@src/lib/get-instances.ts`:
- Around line 8-10: The fetch result is assumed OK and the JSON blindly cast to
InstancesRes; wrap the fetch+res.json() in try/catch, check res.ok and throw or
return a clear error when status is not 2xx, and validate the parsed payload
shape before casting (e.g., check expected top-level fields or Array structure)
so you don't return malformed data; update the block referencing res, data and
InstancesRes to perform these checks and surface/throw a descriptive error on
failure.

In `@src/pages/index.astro`:
- Around line 12-21: The updateData function can throw an unhandled rejection
when getInstances() fails; wrap the await getInstances() call (inside
updateData) in a try/catch (or attach a .catch) and handle errors by logging
them and skipping or providing a safe fallback count before creating the CountUp
instance (referencing updateData, getInstances, CountUp, and instances.total),
ensuring the counter code only runs when instances and instances.total are
valid.

---

Nitpick comments:
In `@src/content/docs/docs/breaking-updates/4-to-5-migrator.astro`:
- Around line 11-13: Replace the hard throw that uses a string when cfgForm or
cfgNew is missing with a graceful early return: detect the missing elements
(cfgForm, cfgNew), log a clear error (e.g., console.error or the page logger)
including which element is missing, and then return from the function to avoid
breaking the page instead of throwing; ensure any downstream code checks for
those elements before proceeding.

In `@src/content/docs/docs/breaking-updates/4-to-5.mdx`:
- Line 9: Replace the informal/wordy phrases in
src/content/docs/docs/breaking-updates/4-to-5.mdx: at Line 9 change "In order to
follow this migration guide, you need to have Tinyauth v4 running." to a shorter
neutral form (e.g. "This migration guide requires Tinyauth v4; migrate from v3
to v4 first and see /docs/breaking-updates/3-to-4."), at Line 16 replace any
"was a mess" phrasing with neutral, specific language (e.g. "was complex" or
"required significant changes"), and at Line 36 replace "quite powerful" with a
concise, objective descriptor like "feature-rich" or "flexible"; keep tone
professional and concise across these sentences.

In `@src/content/docs/docs/getting-started.mdx`:
- Around line 91-95: The snippet shown (keys like image, restart, environment
and env vars TINYAUTH_APPURL / TINYAUTH_AUTH_USERS) is a docker-compose service
fragment and should be labeled as such; update the surrounding text to
explicitly say this is a "service fragment" (or add the top-level "services:"
context) so readers know they must place the block under a services:
<service_name>: entry in their docker-compose.yml rather than copy-pasting the
indented keys at root.

In `@src/content/docs/docs/guides/pocket-id.mdx`:
- Around line 53-72: Admonition blocks (the :::note and :::caution sections)
contain inconsistent leading spaces causing some lines to render as code; remove
all leading indentation inside each admonition so the content lines start
directly after the admonition marker (e.g., adjust the blocks that begin with
":::note" and ":::caution" so their inner lines have no leading spaces),
ensuring each paragraph line under the ::: markers is left-aligned and not
prefixed by 2–4 spaces to prevent accidental code-block formatting.

In `@src/content/docs/docs/guides/runtipi.mdx`:
- Line 39: Break the dense single-paragraph instruction (the paragraph starting
"Navigate to the appstore tab, select the Tinyauth app, and fill in the users,
OAuth credentials...") into a short ordered list of 4–6 concise steps: 1) open
the Appstore tab and select Tinyauth, 2) fill in users and OAuth credentials, 3)
enable either the local domain switch or the expose switch for domain
accessibility and cookie handling, 4) choose the appropriate app URL (local or
exposed) and ensure it uses HTTPS, and 5) complete the installation; keep each
bullet one sentence and preserve the original guidance about cookie handling and
HTTPS.

In `@src/content/docs/docs/guides/using-the-binary.mdx`:
- Around line 86-90: Replace the multi-line inline code span in the note with a
fenced code block so the ExecStart example is easy to read and copy: remove the
wrapped inline backticks and instead insert a triple-backtick fenced block
(optionally labeled "ini") containing a single line with
ExecStart=/some/path/tinyauth --appurl=https://tinyauth.example.com; keep the
surrounding prose about removing EnvironmentFile and the note block intact.

In `@src/content/docs/docs/reference/labels.mdx`:
- Line 42: The table entry for tinyauth.apps.[app].ldap.groups uses "comma
separated" while static analysis prefers "comma-separated" and the file
currently has inconsistent usage; search the document for all occurrences of
"comma separated" and either (a) change this single entry to match the existing
"comma separated" wording for consistency, or (b) update every occurrence
(including the table rows describing labels and descriptions such as the
tinyauth.apps.[app].ldap.groups row) to the hyphenated "comma-separated" so the
file is consistent; pick one approach and apply the replacement across the file.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a980639 and b4a6491.

⛔ Files ignored due to path filters (61)
  • bun.lock is excluded by !**/*.lock
  • public/favicon.ico is excluded by !**/*.ico
  • public/favicon.svg is excluded by !**/*.svg
  • public/screenshots/github-app-client-secret.png is excluded by !**/*.png
  • public/screenshots/github-app-email.png is excluded by !**/*.png
  • public/screenshots/github-app-home.png is excluded by !**/*.png
  • public/screenshots/github-app-new.png is excluded by !**/*.png
  • public/screenshots/github-new-oauth-app.png is excluded by !**/*.png
  • public/screenshots/github-oauth-app-homepage.png is excluded by !**/*.png
  • public/screenshots/github-oauth-client-secret.png is excluded by !**/*.png
  • public/screenshots/github/app-email.png is excluded by !**/*.png
  • public/screenshots/github/app-home.png is excluded by !**/*.png
  • public/screenshots/github/app-new.png is excluded by !**/*.png
  • public/screenshots/github/app-secret.png is excluded by !**/*.png
  • public/screenshots/github/oauth-home.png is excluded by !**/*.png
  • public/screenshots/github/oauth-new.png is excluded by !**/*.png
  • public/screenshots/github/oauth-secret.png is excluded by !**/*.png
  • public/screenshots/google-cloud-home.png is excluded by !**/*.png
  • public/screenshots/google-cloud-oauth-configure.png is excluded by !**/*.png
  • public/screenshots/google-cloud-oauth-created.png is excluded by !**/*.png
  • public/screenshots/google-cloud-oauth-home.png is excluded by !**/*.png
  • public/screenshots/google/client-created.png is excluded by !**/*.png
  • public/screenshots/google/cloud-home.png is excluded by !**/*.png
  • public/screenshots/google/oauth-configure.png is excluded by !**/*.png
  • public/screenshots/google/oauth-home.png is excluded by !**/*.png
  • public/screenshots/lldap-create-user.png is excluded by !**/*.png
  • public/screenshots/lldap-groups.png is excluded by !**/*.png
  • public/screenshots/lldap/new-group.png is excluded by !**/*.png
  • public/screenshots/lldap/new-user.png is excluded by !**/*.png
  • public/screenshots/lldap/user-assign-group.png is excluded by !**/*.png
  • public/screenshots/lldap/user-groups.png is excluded by !**/*.png
  • public/screenshots/npm-nginx.png is excluded by !**/*.png
  • public/screenshots/npm-tinyauth.png is excluded by !**/*.png
  • public/screenshots/npm/tinyauth-host.png is excluded by !**/*.png
  • public/screenshots/npm/whoami-advanced.png is excluded by !**/*.png
  • public/screenshots/npm/whoami-host.png is excluded by !**/*.png
  • public/screenshots/oidc/authorize.png is excluded by !**/*.png
  • public/screenshots/pocket-id-client-page.png is excluded by !**/*.png
  • public/screenshots/pocket-id-group-home.png is excluded by !**/*.png
  • public/screenshots/pocket-id-home.png is excluded by !**/*.png
  • public/screenshots/pocket-id-new-client.png is excluded by !**/*.png
  • public/screenshots/pocket-id-new-group.png is excluded by !**/*.png
  • public/screenshots/pocketid/client-page.png is excluded by !**/*.png
  • public/screenshots/pocketid/group-home.png is excluded by !**/*.png
  • public/screenshots/pocketid/home.png is excluded by !**/*.png
  • public/screenshots/pocketid/new-client.png is excluded by !**/*.png
  • public/screenshots/pocketid/new-group.png is excluded by !**/*.png
  • public/screenshots/runtipi-enable-advanced-settings.png is excluded by !**/*.png
  • public/screenshots/runtipi-forward-auth-url.png is excluded by !**/*.png
  • public/screenshots/runtipi-install-app-example.png is excluded by !**/*.png
  • public/screenshots/runtipi/advanced-settings-enable.png is excluded by !**/*.png
  • public/screenshots/runtipi/app-auth-enable.png is excluded by !**/*.png
  • public/screenshots/runtipi/forward-auth-url.png is excluded by !**/*.png
  • public/screenshots/tinyauth-dark.png is excluded by !**/*.png
  • public/screenshots/zitadel-configuration-view.png is excluded by !**/*.png
  • public/screenshots/zitadel-redirect-view.png is excluded by !**/*.png
  • public/screenshots/zitadel/app-creds.png is excluded by !**/*.png
  • public/screenshots/zitadel/app-new.png is excluded by !**/*.png
  • public/screenshots/zitadel/project-new.png is excluded by !**/*.png
  • public/tinyauth-dark.png is excluded by !**/*.png
  • public/tinyauth.png is excluded by !**/*.png
📒 Files selected for processing (96)
  • .github/workflows/deploy.yml
  • .gitignore
  • .prettierignore
  • .prettierrc
  • .vscode/settings.json
  • app/app.css
  • app/cli.json
  • app/components/card.tsx
  • app/components/countup.tsx
  • app/components/discord.tsx
  • app/components/github.tsx
  • app/components/language-toggle.tsx
  • app/components/layout/docs/client.tsx
  • app/components/layout/docs/index.tsx
  • app/components/layout/docs/page-client.tsx
  • app/components/layout/docs/page.tsx
  • app/components/layout/home/index.tsx
  • app/components/layout/home/menu.tsx
  • app/components/layout/home/navbar.tsx
  • app/components/layout/page.tsx
  • app/components/layout/shared/client.tsx
  • app/components/layout/shared/index.tsx
  • app/components/mdx-components.tsx
  • app/components/mdx/mermaid.tsx
  • app/components/navigation-menu.tsx
  • app/components/root-toggle.tsx
  • app/components/search-toggle.tsx
  • app/components/search.tsx
  • app/components/sidebar.tsx
  • app/components/theme-toggle.tsx
  • app/components/ui/button.tsx
  • app/components/ui/collapsible.tsx
  • app/components/ui/popover.tsx
  • app/components/ui/scroll-area.tsx
  • app/components/ui/toc-clerk.tsx
  • app/components/ui/toc-thumb.tsx
  • app/components/ui/toc.tsx
  • app/docs/page.tsx
  • app/docs/search.ts
  • app/lib/cn.ts
  • app/lib/is-active.ts
  • app/lib/layout.shared.tsx
  • app/lib/merge-refs.ts
  • app/lib/source.ts
  • app/root.tsx
  • app/routes.ts
  • app/routes/discord.tsx
  • app/routes/home.tsx
  • astro.config.mjs
  • content/docs/community/kubernetes.mdx
  • content/docs/community/zitadel-oauth.mdx
  • content/docs/guides/totp.mdx
  • content/docs/meta.json
  • content/docs/reference/cli.mdx
  • content/docs/reference/configuration.mdx
  • package.json
  • react-router.config.ts
  • source.config.ts
  • source.generated.ts
  • src/content.config.ts
  • src/content/docs/docs/about.mdx
  • src/content/docs/docs/breaking-updates/3-to-4.mdx
  • src/content/docs/docs/breaking-updates/4-to-5-migrator.astro
  • src/content/docs/docs/breaking-updates/4-to-5.mdx
  • src/content/docs/docs/community/caddy.mdx
  • src/content/docs/docs/community/kubernetes.mdx
  • src/content/docs/docs/community/zitadel-oauth.mdx
  • src/content/docs/docs/contributing/contributing.mdx
  • src/content/docs/docs/getting-started.mdx
  • src/content/docs/docs/guides/access-controls.mdx
  • src/content/docs/docs/guides/advanced.mdx
  • src/content/docs/docs/guides/github-app-oauth.mdx
  • src/content/docs/docs/guides/github-oauth.mdx
  • src/content/docs/docs/guides/google-oauth.mdx
  • src/content/docs/docs/guides/ldap.mdx
  • src/content/docs/docs/guides/nginx-proxy-manager.mdx
  • src/content/docs/docs/guides/oidc.mdx
  • src/content/docs/docs/guides/pocket-id.mdx
  • src/content/docs/docs/guides/runtipi.mdx
  • src/content/docs/docs/guides/totp.mdx
  • src/content/docs/docs/guides/using-the-binary.mdx
  • src/content/docs/docs/reference/changelog.mdx
  • src/content/docs/docs/reference/cli.mdx
  • src/content/docs/docs/reference/configuration.mdx
  • src/content/docs/docs/reference/flow.mdx
  • src/content/docs/docs/reference/headers.mdx
  • src/content/docs/docs/reference/labels.mdx
  • src/content/docs/docs/reference/telemetry.mdx
  • src/lib/4-to-5-config-migrator.ts
  • src/lib/get-instances.ts
  • src/pages/index.astro
  • src/styles/4-to-5.css
  • src/styles/home.css
  • src/styles/theme.css
  • tsconfig.json
  • vite.config.ts
💤 Files with no reviewable changes (57)
  • app/components/search.tsx
  • app/components/github.tsx
  • .prettierignore
  • app/cli.json
  • content/docs/community/kubernetes.mdx
  • app/root.tsx
  • .github/workflows/deploy.yml
  • app/lib/source.ts
  • app/components/layout/docs/client.tsx
  • source.generated.ts
  • app/components/card.tsx
  • app/components/ui/toc-thumb.tsx
  • app/components/discord.tsx
  • react-router.config.ts
  • app/components/layout/docs/page.tsx
  • app/components/mdx-components.tsx
  • app/lib/cn.ts
  • app/components/layout/shared/index.tsx
  • app/components/layout/shared/client.tsx
  • app/components/countup.tsx
  • app/components/layout/home/menu.tsx
  • app/components/mdx/mermaid.tsx
  • source.config.ts
  • app/routes.ts
  • app/components/layout/home/index.tsx
  • content/docs/community/zitadel-oauth.mdx
  • app/lib/layout.shared.tsx
  • app/components/root-toggle.tsx
  • content/docs/reference/cli.mdx
  • .vscode/settings.json
  • app/components/ui/toc.tsx
  • app/components/layout/docs/index.tsx
  • app/components/theme-toggle.tsx
  • app/lib/merge-refs.ts
  • app/components/ui/toc-clerk.tsx
  • content/docs/guides/totp.mdx
  • app/docs/search.ts
  • app/docs/page.tsx
  • app/components/search-toggle.tsx
  • app/components/layout/docs/page-client.tsx
  • app/app.css
  • content/docs/reference/configuration.mdx
  • .prettierrc
  • app/components/ui/collapsible.tsx
  • app/lib/is-active.ts
  • app/components/ui/scroll-area.tsx
  • app/components/ui/popover.tsx
  • content/docs/meta.json
  • app/routes/discord.tsx
  • app/components/language-toggle.tsx
  • app/components/ui/button.tsx
  • app/components/sidebar.tsx
  • app/components/layout/home/navbar.tsx
  • app/routes/home.tsx
  • app/components/navigation-menu.tsx
  • vite.config.ts
  • app/components/layout/page.tsx

Comment thread astro.config.mjs Outdated
Comment thread src/content/docs/docs/breaking-updates/3-to-4.mdx
Comment thread src/content/docs/docs/breaking-updates/3-to-4.mdx
Comment thread src/content/docs/docs/community/kubernetes.mdx Outdated
Comment thread src/content/docs/docs/guides/access-controls.mdx Outdated
Comment thread src/content/docs/docs/reference/changelog.mdx
Comment thread src/content/docs/docs/reference/configuration.mdx
Comment thread src/lib/4-to-5-config-migrator.ts
Comment thread src/styles/home.css
Comment thread src/styles/theme.css Outdated
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

♻️ Duplicate comments (5)
src/content/docs/docs/community/kubernetes.mdx (1)

60-63: ⚠️ Potential issue | 🟠 Major

Move TINYAUTH_AUTH_USERS out of inline env values into a Secret.

Line 63 still embeds credential material directly in the Deployment manifest, which is an unsafe copy/paste default.

Suggested doc update
           env:
             - name: TINYAUTH_APPURL
               value: http://auth.example.com
             - name: TINYAUTH_AUTH_USERS
-              value: user:$$2a$$10$$UdLYoJ5lgPsC0RKqYH/jMua7zIn0g9kPqWmhYayJYLaZQ/FTmH2/u # Username is user and password is password
+              valueFrom:
+                secretKeyRef:
+                  name: tinyauth-auth-users
+                  key: users
apiVersion: v1
kind: Secret
metadata:
  name: tinyauth-auth-users
  namespace: tinyauth
type: Opaque
stringData:
  users: "<username>:<bcrypt-hash>"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/content/docs/docs/community/kubernetes.mdx` around lines 60 - 63, The
Deployment manifest currently places credentials in the env var
TINYAUTH_AUTH_USERS; move this sensitive data into a Kubernetes Secret named
(for example) tinyauth-auth-users and update the Deployment to reference it via
envFrom or valueFrom:secretKeyRef instead of embedding the bcrypt hash inline.
Create the Secret with the key (e.g., users) holding "<username>:<bcrypt-hash>"
and change the Deployment's container env entry for TINYAUTH_AUTH_USERS to pull
from that Secret (using valueFrom.secretKeyRef or envFrom) so no plaintext
credentials remain in the manifest.
src/content/docs/docs/guides/runtipi.mdx (1)

30-34: ⚠️ Potential issue | 🟡 Minor

Please fix the unresolved “appstore/app stores” wording and grammar.

At Line 31, “multiple app stores support was added” is still awkward. Also normalize “appstore” to “app store” (Line 34 and Line 39) for consistency.

✏️ Suggested text update
-  From Runtipi version v4, multiple app stores support was added. This may change
+  Starting with Runtipi v4, support for multiple app stores was added. This may change
   the container name. If redirection to the Tinyauth login screen fails, use:
-  auth URL (assuming you are installing Tinyauth from the official appstore).
+  auth URL (assuming you are installing Tinyauth from the official app store).
-Navigate to the appstore tab, select the Tinyauth app, and fill in the users, OAuth credentials, and other required information. Before installation, enable either the local domain switch or the expose switch to ensure Tinyauth is accessible via a domain. This is necessary for proper cookie handling. Depending on the setup, use either the local domain or the exposed domain as the app URL (ensure HTTPS is used). Finally, complete the installation process.
+Navigate to the app store tab, select the Tinyauth app, and fill in the users, OAuth credentials, and other required information. Before installation, enable either the local domain switch or the expose switch to ensure Tinyauth is accessible via a domain. This is necessary for proper cookie handling. Depending on the setup, use either the local domain or the exposed domain as the app URL (ensure HTTPS is used). Finally, complete the installation process.

Also applies to: 39-39

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/content/docs/docs/guides/runtipi.mdx` around lines 30 - 34, Edit the
paragraph that begins "From Runtipi version v4..." to fix grammar and normalize
the term "app store": change "multiple app stores support was added" to "support
for multiple app stores was added" and replace any instances of "appstore" with
"app store" (specifically the occurrences in the paragraph and the later
occurrence referenced at lines ~34 and ~39) so the text consistently reads e.g.
"support for multiple app stores" and
"http://tinyauth_migrated-tinyauth-1:3000/api/auth/traefik (assuming you are
installing Tinyauth from the official app store)".
src/content/docs/docs/reference/changelog.mdx (2)

28-28: ⚠️ Potential issue | 🟡 Minor

Use compound-verb hyphenation in release notes (“Auto-create”).

Line 28 still reads “Auto create …”; this was previously flagged and is still unresolved.

✍️ Suggested patch
-- Auto create database directory if it doesn't exist [`@modrin`](https://github.com/modrin)
+- Auto-create database directory if it doesn't exist [`@modrin`](https://github.com/modrin)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/content/docs/docs/reference/changelog.mdx` at line 28, Change the phrase
"Auto create database directory if it doesn't exist [`@modrin`]" to use
compound-verb hyphenation: update the text in the changelog entry (the string
"Auto create database directory if it doesn't exist [`@modrin`]") to "Auto-create
database directory if it doesn't exist [`@modrin`]".

49-49: ⚠️ Potential issue | 🟡 Minor

Fix typo in technical note (paerserparser).

Line 49 still contains the typo previously reported.

✍️ Suggested patch
-- Simplify user parsing logic since we can offload things to paerser
+- Simplify user parsing logic since we can offload things to parser
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/content/docs/docs/reference/changelog.mdx` at line 49, Replace the
misspelled word "paerser" with "parser" in the changelog entry that currently
reads "Simplify user parsing logic since we can offload things to paerser" so it
becomes "Simplify user parsing logic since we can offload things to parser";
locate and update that exact phrase in
src/content/docs/docs/reference/changelog.mdx.
src/content/docs/docs/breaking-updates/3-to-4.mdx (1)

150-159: ⚠️ Potential issue | 🟡 Minor

Fix compound adjective hyphenation.

Line 153 should use "Container-name-based" (fully hyphenated compound adjective) rather than "Container-name based".

✏️ Proposed fix
 :::note
   The label discovery mechanism now uses the app name in the request subdomain.
   For example, `myapp.example.com` matches `tinyauth.apps.myapp.foo: bar`.
-  Container-name based label discovery is no longer supported.
+  Container-name-based label discovery is no longer supported.
 :::
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/content/docs/docs/breaking-updates/3-to-4.mdx` around lines 150 - 159,
Replace the phrase "Container-name based label discovery" with the fully
hyphenated compound adjective "Container-name-based label discovery" in the docs
text block that currently reads "Container-name based label discovery is no
longer supported." to correct hyphenation; update the sentence so it reads
"Container-name-based label discovery is no longer supported." (search for the
exact string "Container-name based label discovery" to locate the change).
🧹 Nitpick comments (5)
src/content/docs/docs/community/kubernetes.mdx (1)

102-104: Reduce repetitive bullet phrasing for readability.

Lines 102-104 start three consecutive bullets with “specifies”; consider varying wording to improve flow.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/content/docs/docs/community/kubernetes.mdx` around lines 102 - 104,
Rewrite the three bullets listed for the nginx ingress annotations to avoid
repeating "specifies" for each line: keep the three annotation keys
(`nginx.ingress.kubernetes.io/auth-url`,
`nginx.ingress.kubernetes.io/auth-signin`,
`nginx.ingress.kubernetes.io/auth-signin-redirect-param`) and change the
verbs/phrasing so they vary (e.g., "sets the URL used by ingress-nginx to verify
authentication", "defines the sign-in redirect URL for unauthenticated users",
"names the query parameter used for the redirect URI"), ensuring each bullet is
concise and reads smoothly.
src/content/docs/docs/guides/runtipi.mdx (1)

39-39: Consider splitting the installation paragraph into steps.

Line 39 is dense and harder to scan. Converting it into an ordered list would improve usability for setup docs.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/content/docs/docs/guides/runtipi.mdx` at line 39, Split the dense
installation paragraph about Tinyauth into a clear ordered list of steps: 1)
Navigate to the appstore tab and select the Tinyauth app; 2) Fill in users,
OAuth credentials, and other required information; 3) Before installation,
enable either the local domain switch or the expose switch so Tinyauth is
accessible via a domain (important for cookie handling); 4) Choose the correct
app URL based on your setup (use the local domain or the exposed domain) and
ensure HTTPS; 5) Complete the installation process — replace the original
single-sentence installation paragraph in
src/content/docs/docs/guides/runtipi.mdx with this ordered list for better
scannability.
src/styles/theme.css (1)

5-13: Optional cleanup: merge adjacent :root blocks.

Line 1-3 and Line 5-8 can be combined to reduce selector duplication and make theme tokens easier to scan.

♻️ Suggested refactor
-:root {
-    --sl-hue-base: 140;
-}
-
-:root {
-    --sl-color-accent: `#fafafa`;
-    --sl-color-accent-high: `#f5f5f5`;
-}
+:root {
+    --sl-hue-base: 140;
+    --sl-color-accent: `#fafafa`;
+    --sl-color-accent-high: `#f5f5f5`;
+}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/styles/theme.css` around lines 5 - 13, Move common token declarations
into a single :root block and keep only overrides inside
:root[data-theme="light"]: specifically consolidate the two blocks that set
--sl-color-accent and --sl-color-accent-high so the base values live once in
:root and the theme-specific values remain in :root[data-theme="light"]; update
or remove duplicate declarations so :root contains the defaults and
:root[data-theme="light"] only overrides those variables.
src/lib/4-to-5-config-migrator.ts (1)

107-121: Silent key drops may confuse users.

When migrateMap encounters an unmapped key, it silently skips it. Users won't know which config options were dropped. Consider logging or returning the unmapped keys so users can manually handle them.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/4-to-5-config-migrator.ts` around lines 107 - 121, The migrateMap
function currently drops unmapped keys silently; update migrateMap (and its
callers) to surface dropped keys by collecting unmapped keys during the loop and
either (A) accept an optional logger parameter and emit a warning listing those
keys (useful when callers can handle side-effect logging) or (B) change the
return shape from Record<string,string> to { migrated: Record<string,string>,
dropped: string[] } so callers of migrateMap (which reference
CONFIG_ENV_KEYS_MAP or CONFIG_CLI_KEYS_MAP) can inspect and report them; ensure
you update all call sites to handle the new logger parameter or return shape and
preserve existing migrated behavior.
src/content/docs/docs/guides/access-controls.mdx (1)

188-194: Add env-var equivalent in the LDAP groups example for consistency.

Line 94 says env vars apply throughout, but this subsection only shows labels. Adding the env-var form would remove ambiguity for static-config deployments.

📝 Suggested addition
 Tinyauth also supports fetching the user's groups from the LDAP server and using them for access control. To use LDAP groups, add the `ldap.groups` label:
 
 ```yaml
 tinyauth.apps.myapp.ldap.groups: admin

+Or with environment variables:
+
+sh +TINYAUTH_APPS_MYAPP_LDAP_GROUPS=admin +

</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against the current code and only fix it if needed.

In @src/content/docs/docs/guides/access-controls.mdx around lines 188 - 194, Add
the environment-variable equivalent for the LDAP groups example in the "Access
Controls Using LDAP Groups" subsection: next to the existing label example
(tinyauth.apps.myapp.ldap.groups: admin) show the corresponding env var
TINYAUTH_APPS_MYAPP_LDAP_GROUPS=admin so readers using static-config via env
vars see the same configuration option; ensure the example matches
casing/underscores used elsewhere and include it as a short shell code block
immediately after the label example.


</details>

</blockquote></details>

</blockquote></details>

<details>
<summary>🤖 Prompt for all review comments with AI agents</summary>

Verify each finding against the current code and only fix it if needed.

Inline comments:
In @src/content/docs/docs/guides/ldap.mdx:

  • Line 68: The LDAP group filter docs incorrectly say %s is replaced by
    "username" and use nonstandard attribute casing; update the sentence that
    currently shows the filter
    (&(objectclass=groupOfUniqueNames)(uniquemember=%s)) to clarify that %s must
    be substituted with the user value expected by the LDAP schema (typically the
    user's distinguished name for groupOfUniqueNames.uniqueMember), and normalize
    attribute names to standard camelCase (objectClass and uniqueMember) so the
    example becomes clear and accurate for typical LDAP setups.

In @src/content/docs/docs/guides/pocket-id.mdx:

  • Around line 53-55: The admonition block starting with :::note contains a line
    indented by 4 spaces which causes Astro to render it as an indented code block;
    edit the admonition (the :::note block) and reduce the indentation of the line
    that contains TINYAUTH_OAUTH_PROVIDERS_POCKETID_INSECURE=true from 4 spaces to 2
    spaces so it matches the other admonitions and renders as normal text in the
    Pocket ID guide.

In @src/content/docs/docs/reference/cli.mdx:

  • Around line 65-67: The note text in the healthcheck block contains a grammar
    mistake ("result to"); update the sentence in the note that begins with "It is
    advised to not use the healthcheck command..." to replace "result to connection
    issues" with "result in connection issues" so the user-facing docs read
    correctly; locate the healthcheck note block (the text starting with "It is
    advised to not use the healthcheck command with the public URL of Tinyauth...")
    and apply this single-word correction.
  • Line 156: Change the phrase "Tinyauth can auto generate TOTP codes for you" to
    use a hyphenated or rephrased form for readability; locate the sentence
    containing "Tinyauth can auto generate TOTP codes for you, the combination is
    username:hash:secret" and replace "auto generate" with "auto-generate" (or
    "automatically generate") so the line reads e.g. "Tinyauth can auto-generate
    TOTP codes for you, the combination is username:hash:secret."

In @src/lib/4-to-5-config-migrator.ts:

  • Around line 92-100: The current parsing uses line.trim().split("--") which
    breaks values containing "--"; change the logic to detect and remove only the
    leading "--" instead of splitting on every occurrence: use the trimmed line
    (replace usages of flagTrimmed and flag) to check startsWith("--") and then take
    substring(2) to get the full flag text, then continue with the existing
    flagSplit/key/value/res assignment so values containing "--" are preserved.

Duplicate comments:
In @src/content/docs/docs/breaking-updates/3-to-4.mdx:

  • Around line 150-159: Replace the phrase "Container-name based label discovery"
    with the fully hyphenated compound adjective "Container-name-based label
    discovery" in the docs text block that currently reads "Container-name based
    label discovery is no longer supported." to correct hyphenation; update the
    sentence so it reads "Container-name-based label discovery is no longer
    supported." (search for the exact string "Container-name based label discovery"
    to locate the change).

In @src/content/docs/docs/community/kubernetes.mdx:

  • Around line 60-63: The Deployment manifest currently places credentials in the
    env var TINYAUTH_AUTH_USERS; move this sensitive data into a Kubernetes Secret
    named (for example) tinyauth-auth-users and update the Deployment to reference
    it via envFrom or valueFrom:secretKeyRef instead of embedding the bcrypt hash
    inline. Create the Secret with the key (e.g., users) holding
    ":" and change the Deployment's container env entry for
    TINYAUTH_AUTH_USERS to pull from that Secret (using valueFrom.secretKeyRef or
    envFrom) so no plaintext credentials remain in the manifest.

In @src/content/docs/docs/guides/runtipi.mdx:

  • Around line 30-34: Edit the paragraph that begins "From Runtipi version v4..."
    to fix grammar and normalize the term "app store": change "multiple app stores
    support was added" to "support for multiple app stores was added" and replace
    any instances of "appstore" with "app store" (specifically the occurrences in
    the paragraph and the later occurrence referenced at lines ~34 and ~39) so the
    text consistently reads e.g. "support for multiple app stores" and
    "http://tinyauth_migrated-tinyauth-1:3000/api/auth/traefik (assuming you are
    installing Tinyauth from the official app store)".

In @src/content/docs/docs/reference/changelog.mdx:

  • Line 28: Change the phrase "Auto create database directory if it doesn't exist
    [@modrin]" to use compound-verb hyphenation: update the text in the changelog
    entry (the string "Auto create database directory if it doesn't exist
    [@modrin]") to "Auto-create database directory if it doesn't exist [@modrin]".
  • Line 49: Replace the misspelled word "paerser" with "parser" in the changelog
    entry that currently reads "Simplify user parsing logic since we can offload
    things to paerser" so it becomes "Simplify user parsing logic since we can
    offload things to parser"; locate and update that exact phrase in
    src/content/docs/docs/reference/changelog.mdx.

Nitpick comments:
In @src/content/docs/docs/community/kubernetes.mdx:

  • Around line 102-104: Rewrite the three bullets listed for the nginx ingress
    annotations to avoid repeating "specifies" for each line: keep the three
    annotation keys (nginx.ingress.kubernetes.io/auth-url,
    nginx.ingress.kubernetes.io/auth-signin,
    nginx.ingress.kubernetes.io/auth-signin-redirect-param) and change the
    verbs/phrasing so they vary (e.g., "sets the URL used by ingress-nginx to verify
    authentication", "defines the sign-in redirect URL for unauthenticated users",
    "names the query parameter used for the redirect URI"), ensuring each bullet is
    concise and reads smoothly.

In @src/content/docs/docs/guides/access-controls.mdx:

  • Around line 188-194: Add the environment-variable equivalent for the LDAP
    groups example in the "Access Controls Using LDAP Groups" subsection: next to
    the existing label example (tinyauth.apps.myapp.ldap.groups: admin) show the
    corresponding env var TINYAUTH_APPS_MYAPP_LDAP_GROUPS=admin so readers using
    static-config via env vars see the same configuration option; ensure the example
    matches casing/underscores used elsewhere and include it as a short shell code
    block immediately after the label example.

In @src/content/docs/docs/guides/runtipi.mdx:

  • Line 39: Split the dense installation paragraph about Tinyauth into a clear
    ordered list of steps: 1) Navigate to the appstore tab and select the Tinyauth
    app; 2) Fill in users, OAuth credentials, and other required information; 3)
    Before installation, enable either the local domain switch or the expose switch
    so Tinyauth is accessible via a domain (important for cookie handling); 4)
    Choose the correct app URL based on your setup (use the local domain or the
    exposed domain) and ensure HTTPS; 5) Complete the installation process — replace
    the original single-sentence installation paragraph in
    src/content/docs/docs/guides/runtipi.mdx with this ordered list for better
    scannability.

In @src/lib/4-to-5-config-migrator.ts:

  • Around line 107-121: The migrateMap function currently drops unmapped keys
    silently; update migrateMap (and its callers) to surface dropped keys by
    collecting unmapped keys during the loop and either (A) accept an optional
    logger parameter and emit a warning listing those keys (useful when callers can
    handle side-effect logging) or (B) change the return shape from
    Record<string,string> to { migrated: Record<string,string>, dropped: string[] }
    so callers of migrateMap (which reference CONFIG_ENV_KEYS_MAP or
    CONFIG_CLI_KEYS_MAP) can inspect and report them; ensure you update all call
    sites to handle the new logger parameter or return shape and preserve existing
    migrated behavior.

In @src/styles/theme.css:

  • Around line 5-13: Move common token declarations into a single :root block and
    keep only overrides inside :root[data-theme="light"]: specifically consolidate
    the two blocks that set --sl-color-accent and --sl-color-accent-high so the base
    values live once in :root and the theme-specific values remain in
    :root[data-theme="light"]; update or remove duplicate declarations so :root
    contains the defaults and :root[data-theme="light"] only overrides those
    variables.

</details>

---

<details>
<summary>ℹ️ Review info</summary>

**Configuration used**: defaults

**Review profile**: CHILL

**Plan**: Pro

<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between b4a64912b82ad48bd92537f988bb8179f135458d and 0cddf62a59feea04b83df08a2733078f101ec874.

</details>

<details>
<summary>📒 Files selected for processing (14)</summary>

* `src/content/docs/docs/breaking-updates/3-to-4.mdx`
* `src/content/docs/docs/breaking-updates/4-to-5.mdx`
* `src/content/docs/docs/community/kubernetes.mdx`
* `src/content/docs/docs/guides/access-controls.mdx`
* `src/content/docs/docs/guides/github-app-oauth.mdx`
* `src/content/docs/docs/guides/ldap.mdx`
* `src/content/docs/docs/guides/nginx-proxy-manager.mdx`
* `src/content/docs/docs/guides/oidc.mdx`
* `src/content/docs/docs/guides/pocket-id.mdx`
* `src/content/docs/docs/guides/runtipi.mdx`
* `src/content/docs/docs/reference/changelog.mdx`
* `src/content/docs/docs/reference/cli.mdx`
* `src/lib/4-to-5-config-migrator.ts`
* `src/styles/theme.css`

</details>

<details>
<summary>🚧 Files skipped from review as they are similar to previous changes (2)</summary>

* src/content/docs/docs/guides/nginx-proxy-manager.mdx
* src/content/docs/docs/guides/oidc.mdx

</details>

</details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->

Comment thread src/content/docs/docs/guides/ldap.mdx
Comment thread src/content/docs/docs/guides/pocket-id.mdx
Comment thread src/content/docs/docs/reference/cli.mdx
Comment thread src/content/docs/docs/reference/cli.mdx Outdated
Comment thread src/lib/4-to-5-config-migrator.ts Outdated
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@astro.config.mjs`:
- Around line 65-68: The label string "Github OAuth" is using incorrect
capitalization; update the label value in the menu/item object (the entry with
label "Github OAuth" and slug "docs/guides/github-oauth") to "GitHub OAuth" so
it matches the other "GitHub OAuth Apps" usage and corrects branding
consistently across the config.
- Around line 29-31: The logo src is using a file-system path
("./public/tinyauth.png") instead of a root-relative URL; update the logo
configuration (the logo object and its src property) to use the site-root path
"/tinyauth.png" so it matches how public files are served (similar to the
favicon entry).

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ff70bc6 and d27677f.

📒 Files selected for processing (1)
  • astro.config.mjs

Comment thread astro.config.mjs
Comment thread astro.config.mjs
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (4)
astro.config.mjs (3)

66-68: ⚠️ Potential issue | 🟡 Minor

Fix branding capitalization for consistency.

Line [67] uses "Github OAuth" while Line [71] uses "GitHub OAuth Apps". Use "GitHub OAuth" for consistent branding.

Suggested fix
             {
-              label: "Github OAuth",
+              label: "GitHub OAuth",
               slug: "docs/guides/github-oauth",
             },
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@astro.config.mjs` around lines 66 - 68, Update the inconsistent branding
string by changing the label value "Github OAuth" to "GitHub OAuth" in the
object where label: "Github OAuth" and slug: "docs/guides/github-oauth" are
defined so it matches the other "GitHub OAuth Apps" entry; locate the object
with the label key and replace the capitalization only.

11-15: ⚠️ Potential issue | 🟠 Major

Restrict server.allowedHosts instead of allowing all hosts.

Line [14] sets allowedHosts: true, which disables host allowlisting and weakens dev/preview server security. Prefer an explicit host list.

Suggested fix
   server: {
     host: "0.0.0.0",
     port: 3000,
-    allowedHosts: true,
+    allowedHosts: ["localhost", "127.0.0.1"],
   },
Astro v5 server.allowedHosts configuration type and security guidance for allowedHosts: true
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@astro.config.mjs` around lines 11 - 15, Replace the permissive
server.allowedHosts: true setting with an explicit allowlist: update the
server.allowedHosts entry (in the server config block where server.host,
server.port are defined) to an array of allowed hostnames/IPs (for example
localhost, 127.0.0.1 and any specific preview hostnames) or to a function that
validates incoming hosts; ensure server.allowedHosts is not a boolean and
contains only the intended hosts to restore host allowlisting for the Astro
dev/preview server.

30-32: ⚠️ Potential issue | 🟡 Minor

Use a root-relative URL for the Starlight logo asset.

Line [31] references ./public/tinyauth.png. Files in public/ should be referenced via root path (e.g., /tinyauth.png), otherwise the logo may not resolve correctly.

Suggested fix
       logo: {
-        src: "./public/tinyauth.png",
+        src: "/tinyauth.png",
       },
Starlight logo src path when image is stored in Astro public directory
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@astro.config.mjs` around lines 30 - 32, Change the logo src to a
root-relative path so the Starlight logo resolves from the Astro public
directory: update the logo.src value (in astro.config.mjs, the logo object) from
"./public/tinyauth.png" to "/tinyauth.png" so the asset is served correctly from
the public/ root.
package.json (1)

22-24: ⚠️ Potential issue | 🟠 Major

Replace exact Node pin with a compatible semver range.

Line [23] pins Node to a single exact version ("v25.5.0"), which is brittle for CI and contributors. Use a supported range for Astro v5 instead.

Suggested fix
   "engines": {
-    "node": "v25.5.0"
+    "node": "^18.17.1 || ^20.3.0 || >=22.0.0"
   }
Astro 5.6.1 engines.node supported versions from official package metadata
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@package.json` around lines 22 - 24, Replace the exact Node pin in
package.json (the "engines.node" value currently set to "v25.5.0") with a
compatible semver range for Astro v5; update the "engines.node" entry to a broad
semver constraint (for example, ">=18.15.0 <26" or the exact supported range
from Astro v5.6.1) so CI and contributors can use compatible Node versions
without being locked to a single patch.
🧹 Nitpick comments (2)
src/content/docs/docs/contributing/contributing.mdx (2)

57-60: Add an explicit command for creating .env to reduce setup ambiguity.

This section says to copy .env.example but does not show the command. Adding it improves contributor success rate.

Suggested doc snippet
 Configuration requires an environment file. Copy the `.env.example` file to `.env` and adjust the environment variables as needed.
+
+```sh
+cp .env.example .env
+```
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/content/docs/docs/contributing/contributing.mdx` around lines 57 - 60,
The docs ask contributors to copy `.env.example` but lack the actual command;
update the "Create the `.env` file" section in contributing.mdx to include the
explicit shell command to copy the file (cp .env.example .env) shown as a shell
code block so it's discoverable and copy-pastable; ensure the surrounding text
remains (explain to adjust variables) and use the same MDX formatting style as
nearby examples for consistency.

36-36: Tighten wording in patch instructions for readability.

Line 36 is a comma-splice and can be simplified for clarity.

Suggested wording
-Some of the dependencies must be patched in order to work correctly with the project, you can apply the patches by running:
+Some dependencies must be patched to work correctly with the project. Apply them with:
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/content/docs/docs/contributing/contributing.mdx` at line 36, Replace the
comma-spliced sentence "Some of the dependencies must be patched in order to
work correctly with the project, you can apply the patches by running:" with a
clearer, tighter phrasing such as splitting into two sentences: "Some
dependencies must be patched to work correctly with the project. Apply the
patches by running:"; update the fragment in contributing.mdx where the sentence
appears (the line starting with "Some of the dependencies must be patched...")
so the wording is concise and uses active voice.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@astro.config.mjs`:
- Around line 66-68: Update the inconsistent branding string by changing the
label value "Github OAuth" to "GitHub OAuth" in the object where label: "Github
OAuth" and slug: "docs/guides/github-oauth" are defined so it matches the other
"GitHub OAuth Apps" entry; locate the object with the label key and replace the
capitalization only.
- Around line 11-15: Replace the permissive server.allowedHosts: true setting
with an explicit allowlist: update the server.allowedHosts entry (in the server
config block where server.host, server.port are defined) to an array of allowed
hostnames/IPs (for example localhost, 127.0.0.1 and any specific preview
hostnames) or to a function that validates incoming hosts; ensure
server.allowedHosts is not a boolean and contains only the intended hosts to
restore host allowlisting for the Astro dev/preview server.
- Around line 30-32: Change the logo src to a root-relative path so the
Starlight logo resolves from the Astro public directory: update the logo.src
value (in astro.config.mjs, the logo object) from "./public/tinyauth.png" to
"/tinyauth.png" so the asset is served correctly from the public/ root.

In `@package.json`:
- Around line 22-24: Replace the exact Node pin in package.json (the
"engines.node" value currently set to "v25.5.0") with a compatible semver range
for Astro v5; update the "engines.node" entry to a broad semver constraint (for
example, ">=18.15.0 <26" or the exact supported range from Astro v5.6.1) so CI
and contributors can use compatible Node versions without being locked to a
single patch.

---

Nitpick comments:
In `@src/content/docs/docs/contributing/contributing.mdx`:
- Around line 57-60: The docs ask contributors to copy `.env.example` but lack
the actual command; update the "Create the `.env` file" section in
contributing.mdx to include the explicit shell command to copy the file (cp
.env.example .env) shown as a shell code block so it's discoverable and
copy-pastable; ensure the surrounding text remains (explain to adjust variables)
and use the same MDX formatting style as nearby examples for consistency.
- Line 36: Replace the comma-spliced sentence "Some of the dependencies must be
patched in order to work correctly with the project, you can apply the patches
by running:" with a clearer, tighter phrasing such as splitting into two
sentences: "Some dependencies must be patched to work correctly with the
project. Apply the patches by running:"; update the fragment in contributing.mdx
where the sentence appears (the line starting with "Some of the dependencies
must be patched...") so the wording is concise and uses active voice.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d27677f and 9e4cfcf.

⛔ Files ignored due to path filters (1)
  • bun.lock is excluded by !**/*.lock
📒 Files selected for processing (3)
  • astro.config.mjs
  • package.json
  • src/content/docs/docs/contributing/contributing.mdx

@steveiliop56 steveiliop56 merged commit 306b55b into main Mar 2, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants