Skip to content

feat: implement live demo sign-in functionality with prefilled credentials#34

Merged
JoachimLK merged 2 commits intomainfrom
JoachimLK/issue33
Feb 21, 2026
Merged

feat: implement live demo sign-in functionality with prefilled credentials#34
JoachimLK merged 2 commits intomainfrom
JoachimLK/issue33

Conversation

@JoachimLK
Copy link
Copy Markdown
Contributor

@JoachimLK JoachimLK commented Feb 21, 2026

Summary

  • What does this PR change?
  • Why is this needed?

Type of change

  • Bug fix
  • Feature
  • Refactor
  • Docs
  • Chore

Validation

  • I tested locally
  • I added/updated relevant documentation
  • I verified multi-tenant scoping and auth behavior for affected API paths

DCO

  • All commits in this PR are signed off (Signed-off-by) via git commit -s

Summary by CodeRabbit

  • New Features

    • Added a dedicated link that opens a pre-filled sign-in page for live demos when accessed with the live-demo parameter.
    • Public runtime settings now support configurable demo credentials to enable the prefill.
  • Improvements

    • Removed the inline one-click demo button and related loading indicators from the landing page for a simpler experience.

@railway-app railway-app Bot temporarily deployed to applirank / applirank-pr-34 February 21, 2026 14:09 Destroyed
@railway-app
Copy link
Copy Markdown

railway-app Bot commented Feb 21, 2026

🚅 Deployed to the applirank-pr-34 environment in applirank

Service Status Web Updated (UTC)
applirank ✅ Success (View Logs) Web Feb 21, 2026 at 2:21 pm

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Feb 21, 2026

No actionable comments were generated in the recent review. 🎉


📝 Walkthrough

Walkthrough

Landing page demo button is replaced by a link to /auth/sign-in?live=1. The sign-in page now reads route and runtime config at setup and, when live=1 is present, pre-fills email and password from runtimeConfig.public.liveDemoEmail and runtimeConfig.public.liveDemoSecret. Nuxt config adds those public runtime variables and Railway preview detection.

Changes

Cohort / File(s) Summary
Sign-in page
app/pages/auth/sign-in.vue
Adds useRoute() and useRuntimeConfig() in setup; when route.query.live === '1' pre-fills form email and password from runtimeConfig.public.liveDemoEmail and runtimeConfig.public.liveDemoSecret.
Landing page
app/pages/index.vue
Removes one-click demo logic (loading state, tryDemo function, demo button) and replaces demo button with a NuxtLink to /auth/sign-in?live=1.
Nuxt runtime config
nuxt.config.ts
Adds Railway environment detection and two public runtime config properties: liveDemoEmail and liveDemoSecret, populated via prioritized environment-variable fallbacks and Railway preview defaults.

Sequence Diagram(s)

sequenceDiagram
  participant User as User
  participant Browser as Browser
  participant Index as IndexPage
  participant SignIn as SignInPage
  participant Config as RuntimeConfig

  User->>Index: click "Demo" link
  Index->>Browser: navigate to /auth/sign-in?live=1
  Browser->>SignIn: load page (query: live=1)
  SignIn->>SignIn: setup() calls useRoute(), useRuntimeConfig()
  SignIn->>Config: read runtimeConfig.public.liveDemoEmail / liveDemoSecret
  Config-->>SignIn: return demo credentials
  SignIn->>SignIn: if route.query.live === '1' set form.email/password
  SignIn-->>Browser: render sign-in form with pre-filled credentials
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Poem

🐰 I hopped from button to a link so spry,
Query in tow beneath the sky.
Env secrets tucked into a form,
A demo breeze that’s soft and warm.
Hop on in — no extra try! 🥕✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The PR description uses only the template structure without filling in any required content; the Summary section is empty, no change type is selected, and no validation items are checked. Complete the Summary section describing what changed and why, select the appropriate Type of change (Feature), and confirm validation steps completed. Add commit sign-off confirmation if applicable.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: implementing live demo sign-in with prefilled credentials from config, which is reflected across all three modified files.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch JoachimLK/issue33

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.

Copy link
Copy Markdown

@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

🧹 Nitpick comments (1)
app/pages/index.vue (1)

178-184: Play icon: prefer size-* utility per icon-sizing guidelines

The Play icon uses h-3.5 w-3.5 instead of the size-3.5 shorthand. Also worth considering: since the sign-in page carries middleware: ['guest'], authenticated users who click this button are silently redirected to their dashboard rather than seeing the demo — hiding the CTA behind v-if="!session" would be more intentional.

♻️ Proposed fix
-            <Play class="h-3.5 w-3.5" />
+            <Play class="size-3.5" />

As per coding guidelines: "Size Lucide icons with Tailwind size-* utilities (e.g., size-5); color with text-* utilities."

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

In `@app/pages/index.vue` around lines 178 - 184, Replace the explicit Tailwind
height/width on the Play icon with the size-* utility and conditionally hide the
CTA for authenticated users: in the NuxtLink containing <Play class="h-3.5
w-3.5" />, change the icon class to use the size-3.5 utility (e.g.,
class="size-3.5") and apply text-* utilities for color as needed, and wrap the
NuxtLink in a v-if="!session" (or equivalent session-check used across the app)
so authenticated users won’t see the demo CTA and won’t be redirected by the
sign-in middleware.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@nuxt.config.ts`:
- Around line 50-52: The runtimeConfig.public currently exposes liveDemoSecret
(and liveDemoEmail) to every page payload; either rename liveDemoSecret to
liveDemoPassword to make the intentional exposure explicit (update references to
liveDemoSecret across the codebase), or move liveDemoEmail and liveDemoSecret
into the private runtimeConfig (server-only) and implement a server route (e.g.,
GET /api/demo-credentials) that returns those values on demand; ensure the
client requests that endpoint only when live mode is needed (e.g., when
?live=1), and update any code that previously read
runtimeConfig.public.liveDemoSecret/liveDemoEmail to use the new API or renamed
key.
- Around line 49-52: Update runtimeConfig to read public runtime env vars using
the NUXT_PUBLIC_* naming (e.g., replace process.env.DEMO_EMAIL and
process.env.DEMO_PASSWORD with process.env.NUXT_PUBLIC_DEMO_EMAIL and
process.env.NUXT_PUBLIC_DEMO_PASSWORD) so values can be overridden at runtime,
and in the sign-in component (the prefill logic that references liveDemoEmail
and liveDemoSecret) only apply the demo prefill when both liveDemoEmail and
liveDemoSecret are present/non-empty to avoid partial prefilling that blocks
form submission.

---

Nitpick comments:
In `@app/pages/index.vue`:
- Around line 178-184: Replace the explicit Tailwind height/width on the Play
icon with the size-* utility and conditionally hide the CTA for authenticated
users: in the NuxtLink containing <Play class="h-3.5 w-3.5" />, change the icon
class to use the size-3.5 utility (e.g., class="size-3.5") and apply text-*
utilities for color as needed, and wrap the NuxtLink in a v-if="!session" (or
equivalent session-check used across the app) so authenticated users won’t see
the demo CTA and won’t be redirected by the sign-in middleware.

Comment thread nuxt.config.ts Outdated
Comment on lines +49 to +52
/** Public live-demo account email used to prefill sign-in */
liveDemoEmail: process.env.DEMO_EMAIL || 'demo@applirank.com',
/** Public live-demo secret used to prefill sign-in */
liveDemoSecret: process.env.DEMO_PASSWORD || '',
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

Nuxt 4 runtimeConfig environment variables NUXT_PUBLIC_ prefix runtime override

💡 Result:

In Nuxt 4, runtimeConfig values can be overridden at runtime (when the server starts) via specially named environment variables, as long as the keys are declared in nuxt.config. (dev.nuxt.com)

1) Prefix rules (NUXT_ and NUXT_PUBLIC_)

  • Private (server-only): runtimeConfig.someKey ⇢ override with NUXT_SOME_KEY
  • Public (exposed to client): runtimeConfig.public.someKey ⇢ override with NUXT_PUBLIC_SOME_KEY (dev.nuxt.com)

Nuxt matches by:

  • Uppercasing
  • Using _ separators for nested keys (including public) (dev.nuxt.com)

Example

// nuxt.config.ts
export default defineNuxtConfig({
  runtimeConfig: {
    apiSecret: '',
    public: {
      apiBase: ''
    }
  }
})

Runtime overrides:

NUXT_API_SECRET="server-secret"
NUXT_PUBLIC_API_BASE="https://api.example.com"

(dev.nuxt.com)

2) The common mistake that breaks runtime overrides

If you do this:

runtimeConfig: {
  public: {
    apiBase: process.env.API_BASE
  }
}

…it will be resolved at build time, so changing env vars later often won’t affect the deployed app (common in platforms that only inject env at build time). Instead, set defaults in runtimeConfig and override with NUXT_... env vars at runtime. (dev.nuxt.com)

3) “Runtime override” caveat (SSR vs static)

  • SSR / Node server: env vars are read when the built server runs; public runtime config is then serialized into the page payload. (dev.nuxt.com)
  • Static generate (pre-render): values are effectively baked into output at generate time; changing env vars later won’t update already-generated pages. (Same practical limitation described by deploy/build-only environments.) (github.com)

4) .env in production

Nuxt reads .env in development/build, but the built server does not automatically read .env in production—use real platform env vars for runtime overrides. (dev.nuxt.com)

Citations:


🏁 Script executed:

# Find and examine nuxt.config.ts
fd -t f "nuxt.config.ts" | head -1 | xargs cat -n

Repository: applirank/applirank

Length of output: 5394


🏁 Script executed:

fd -t f "sign-in.vue" | xargs cat -n | head -100

Repository: applirank/applirank

Length of output: 3685


Fix environment variable naming and prevent partial demo prefill when credentials are unconfigured

The env var names DEMO_EMAIL and DEMO_PASSWORD are resolved at build-time and won't override the config at runtime. In Nuxt 4, only environment variables matching the NUXT_PUBLIC_* convention (converted to uppercase with underscores) can override public runtimeConfig values after deployment.

Additionally, since liveDemoSecret defaults to an empty string, if DEMO_PASSWORD is not set, the form prefills the email but leaves the password blank. The required HTML validation then blocks submission with no guidance, breaking the demo.

Update to use proper environment variable naming and guard the prefill:

Proposed fix
-      liveDemoEmail: process.env.DEMO_EMAIL || 'demo@applirank.com',
-      liveDemoSecret: process.env.DEMO_PASSWORD || '',
+      liveDemoEmail: process.env.NUXT_PUBLIC_LIVE_DEMO_EMAIL || 'demo@applirank.com',
+      liveDemoPassword: process.env.NUXT_PUBLIC_LIVE_DEMO_PASSWORD || '',

In sign-in.vue, guard the prefill to avoid partial application:

-if (route.query.live === '1') {
-  email.value = config.public.liveDemoEmail
-  password.value = config.public.liveDemoSecret
-}
+if (route.query.live === '1' && config.public.liveDemoEmail && config.public.liveDemoPassword) {
+  email.value = config.public.liveDemoEmail
+  password.value = config.public.liveDemoPassword
-}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
/** Public live-demo account email used to prefill sign-in */
liveDemoEmail: process.env.DEMO_EMAIL || 'demo@applirank.com',
/** Public live-demo secret used to prefill sign-in */
liveDemoSecret: process.env.DEMO_PASSWORD || '',
/** Public live-demo account email used to prefill sign-in */
liveDemoEmail: process.env.NUXT_PUBLIC_LIVE_DEMO_EMAIL || 'demo@applirank.com',
/** Public live-demo secret used to prefill sign-in */
liveDemoPassword: process.env.NUXT_PUBLIC_LIVE_DEMO_PASSWORD || '',
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@nuxt.config.ts` around lines 49 - 52, Update runtimeConfig to read public
runtime env vars using the NUXT_PUBLIC_* naming (e.g., replace
process.env.DEMO_EMAIL and process.env.DEMO_PASSWORD with
process.env.NUXT_PUBLIC_DEMO_EMAIL and process.env.NUXT_PUBLIC_DEMO_PASSWORD) so
values can be overridden at runtime, and in the sign-in component (the prefill
logic that references liveDemoEmail and liveDemoSecret) only apply the demo
prefill when both liveDemoEmail and liveDemoSecret are present/non-empty to
avoid partial prefilling that blocks form submission.

Comment thread nuxt.config.ts Outdated
Comment on lines +50 to +52
liveDemoEmail: process.env.DEMO_EMAIL || 'demo@applirank.com',
/** Public live-demo secret used to prefill sign-in */
liveDemoSecret: process.env.DEMO_PASSWORD || '',
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Demo password exposed in every page's Nuxt payload via runtimeConfig.public

When a value is added to runtimeConfig.public, Nuxt adds it to each page payload, making it universally accessible in both server and browser. This means liveDemoSecret (the demo account password) is readable by anyone who inspects the HTML source of any page on the site, not just the sign-in page — and it is also available in the client-side JavaScript.

Even for an intentionally-public demo account, placing a credential here has two concrete downsides:

  • The word "Secret" in a runtimeConfig.public field is contradictory and signals a misuse of the config boundary to future contributors.
  • If the demo account ever gets write access or is reused across environments, the passive credential exposure becomes a liability.

Option A (accept the trade-off, fix naming): Rename to liveDemoPassword to clearly signal the intentional exposure:

🔑 Option A — rename only
-      /** Public live-demo account email used to prefill sign-in */
-      liveDemoEmail: process.env.DEMO_EMAIL || 'demo@applirank.com',
-      /** Public live-demo secret used to prefill sign-in */
-      liveDemoSecret: process.env.DEMO_PASSWORD || '',
+      /** Public live-demo account email used to prefill sign-in */
+      liveDemoEmail: process.env.DEMO_EMAIL || 'demo@applirank.com',
+      /** Public live-demo account password used to prefill sign-in */
+      liveDemoPassword: process.env.DEMO_PASSWORD || '',

Option B (reduce passive exposure): Move both fields to the private runtimeConfig block (server-only) and add a thin GET /api/demo-credentials server route that returns them only on request, called client-side when ?live=1 is detected. This limits exposure to users who actively visit the sign-in page with the live flag.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
liveDemoEmail: process.env.DEMO_EMAIL || 'demo@applirank.com',
/** Public live-demo secret used to prefill sign-in */
liveDemoSecret: process.env.DEMO_PASSWORD || '',
liveDemoEmail: process.env.DEMO_EMAIL || 'demo@applirank.com',
/** Public live-demo account password used to prefill sign-in */
liveDemoPassword: process.env.DEMO_PASSWORD || '',
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@nuxt.config.ts` around lines 50 - 52, The runtimeConfig.public currently
exposes liveDemoSecret (and liveDemoEmail) to every page payload; either rename
liveDemoSecret to liveDemoPassword to make the intentional exposure explicit
(update references to liveDemoSecret across the codebase), or move liveDemoEmail
and liveDemoSecret into the private runtimeConfig (server-only) and implement a
server route (e.g., GET /api/demo-credentials) that returns those values on
demand; ensure the client requests that endpoint only when live mode is needed
(e.g., when ?live=1), and update any code that previously read
runtimeConfig.public.liveDemoSecret/liveDemoEmail to use the new API or renamed
key.

@railway-app railway-app Bot temporarily deployed to applirank / applirank-pr-34 February 21, 2026 14:19 Destroyed
@JoachimLK JoachimLK merged commit 8cc6c86 into main Feb 21, 2026
4 checks 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.

1 participant