feat(cli): seed auth.json from env-supplied credentials (2/3)#537
feat(cli): seed auth.json from env-supplied credentials (2/3)#537moranshe-max wants to merge 1 commit into
Conversation
🚀 Package Preview Available!Install this PR's preview build with npm: npm i @base44-preview/cli@0.0.54-pr.537.b493243Prefer not to change any import paths? Install using npm alias so your code still imports npm i "base44@npm:@base44-preview/cli@0.0.54-pr.537.b493243"Or add it to your {
"dependencies": {
"base44": "npm:@base44-preview/cli@0.0.54-pr.537.b493243"
}
}
Preview published to npm registry — try new features instantly! |
dd70d92 to
e502594
Compare
ab0b4ea to
54f3fe5
Compare
| `BASE44_API_URL`): for each, if the bare name is unset and exactly one | ||
| `<PREFIX>_<KEY>` variable exists, its value is copied to the bare name. This is | ||
| prefix-agnostic and leaves the bare key unset when ambiguous. | ||
|
|
There was a problem hiding this comment.
I feel that this is too verbose, and we can minimize it. Not sure what's the value for the agent (not that i know if the AGENTS.md helps at all...)
| * | ||
| * @returns true if an auth file was written. | ||
| */ | ||
| export async function seedAuthFromEnv(): Promise<boolean> { |
There was a problem hiding this comment.
It seems like this returned boolean is not used anywhere
| /** | ||
| * Decodes a JWT payload's claims WITHOUT verifying the signature (display/expiry | ||
| * use only — the server still validates the token). Returns null for non-JWTs. | ||
| */ |
There was a problem hiding this comment.
I think we can remove this comment
| * form a standard record (not a JWT with `exp`, or no refresh token). | ||
| * | ||
| * @returns true if an auth file was written. | ||
| */ |
There was a problem hiding this comment.
Remove / minimize comment
There was a problem hiding this comment.
I really should add a rule to AGENTS.md or something
| } | ||
|
|
||
| normalizeBase44Env(); | ||
| } |
There was a problem hiding this comment.
All this can be replaced with a call to config() function from dotenv
| process.env[bareKey] = process.env[matches[0]]; | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
I would consider removing it if we expect specific env vars for now. even make the BASE44_ENV_KEYS to hold the specific STRIPE keys if they are static
| @@ -1,3 +1,5 @@ | |||
| // Must stay first — see bootstrap-env.js. | |||
| import "@/cli/bootstrap-env.js"; | |||
There was a problem hiding this comment.
Ok lets remove this, and add an import to import { loadProjectEnvFiles } from "@/core/utils/env.js"; and inside runCLI function lets use findProjectRoot and pass it into loadProjectEnvFiles?
There was a problem hiding this comment.
notice that loadProjectEnvFiles may return empty route if .app.jsonc not found
| // Must run before any module reads env-derived config at import time — notably | ||
| // the HTTP clients, which capture getBase44ApiUrl() when ky.create() runs at | ||
| // module load. Imported first in cli/index.ts so it initializes ahead of them. | ||
| loadProjectEnvFiles(); |
There was a problem hiding this comment.
I commented in index.ts file, i think this file should be removed
| * Decodes a JWT payload's claims WITHOUT verifying the signature (display/expiry | ||
| * use only — the server still validates the token). Returns null for non-JWTs. | ||
| */ | ||
| function decodeJwtClaims(token: string): Record<string, unknown> | null { |
There was a problem hiding this comment.
Artem added jsonwebtoken package for the dev server, can we use it here as well? no need to decode ourselved
| * never overridden). Synchronous so it can run during bootstrap, before the HTTP | ||
| * clients capture `getBase44ApiUrl()`. | ||
| */ | ||
| export function loadProjectEnvFiles(cwd: string = process.cwd()): void { |
There was a problem hiding this comment.
change cwd to be "projectRoot" because we want to support the user running either from the project root, or from ~/my-project/base44 .. we don't want to force the user to be on the project root for this to work
| const b64url = (obj: Record<string, unknown>) => | ||
| Buffer.from(JSON.stringify(obj)).toString("base64url"); | ||
| return `${b64url({ alg: "none", typ: "JWT" })}.${b64url(claims)}.sig`; | ||
| } |
There was a problem hiding this comment.
consider of jsonwebtoken package can resolve this for you?
kfirstri
left a comment
There was a problem hiding this comment.
Added some comments, and i think we can tell the AI to chill with the comments :P
a74b402 to
9ee4aa1
Compare
54f3fe5 to
8cc7307
Compare
9ee4aa1 to
d77abe1
Compare
Enables non-interactive credential handoff (CI, agents, provisioning tools) by seeding the standard auth file from the environment, instead of special-casing env vars throughout the token flow: - The `ensureAuth` middleware calls `seedAuthFromEnv()` before the login check: when BASE44_ACCESS_TOKEN is set it decodes the JWT (sub -> email, exp -> expiresAt), reads BASE44_REFRESH_TOKEN, and writes a standard ~/.base44/auth/auth.json. readAuth / base44Client / isLoggedIn / whoami / refresh then all use one plain file-based path (no per-call-site special-casing; base44-client.ts and whoami.ts are untouched). - Overwrites an existing login when env vars are present (env = source of truth); no-ops when the creds can't form a standard record (not a JWT with exp, or no refresh token). - Loads .env/.env.local at startup via cli/bootstrap-env.ts (first import, before the HTTP clients capture getBase44ApiUrl()). - Normalizes prefix-namespaced vars (e.g. <PREFIX>_BASE44_APP_ID) to the bare BASE44_* names; prefix-agnostic and left unset when ambiguous. Adds a givenEnv testkit helper plus env-seeding and env-normalization specs. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
8cc7307 to
9daf582
Compare
Note
Description
Adds support for seeding authentication from environment-supplied credentials so non-interactive flows (CI, agents, provisioning tools like the Stripe Projects CLI) can run the CLI with no manual `base44 login`. When `BASE44_ACCESS_TOKEN` and `BASE44_REFRESH_TOKEN` are present, the `ensureAuth` middleware decodes the access-token JWT and writes a standard `~/.base44/auth/auth.json`, so all downstream code uses one file-based auth path. Credentials are also loaded from project-local `.env`/`.env.local` at startup, with normalization of the Stripe Projects CLI's `BASE44_PROJECTS_BASE44_` variables to their bare `BASE44_` names.
Related Issue
None
Type of Change
Changes Made
Testing
Checklist
Additional Notes
The seeded file behaves like a normal login: a 401 triggers the usual refresh, and if refresh fails the file is deleted and self-heals on the next command (re-seeded from the still-present env vars). Adds a new dependency on `jsonwebtoken` for decoding the access token.
Generated by Claude | 2026-06-10 12:32 UTC | b493243