mirror of
https://github.com/hcengineering/platform.git
synced 2026-08-17 18:05:42 +02:00
* feat(password): add email-confirmed password setup for SSO accounts SSO-only accounts (Google, GitHub, OIDC) now have a secure path to add a password credential without requiring direct session trust. **Problem:** Previously, password setup for SSO users either required an existing password (blocking SSO-only users entirely) or would have needed to trust the session token alone to create a persistent credential — a security gap where a compromised session could silently add a password. **Solution:** Email-confirmed flow that reuses the existing recovery infrastructure: 1. `checkHasPassword` RPC — authenticates via session token, returns whether the account has a password hash set (drives UI branching). 2. `requestPasswordSetup` RPC — authenticates via session token, looks up the account's verified email social ID, generates a recovery token (`restoreEmail` claim), and sends a "Password recovery" email via the existing mail service. No DB schema changes. 3. `PasswordRestore.svelte` (unchanged) handles the link click → calls the existing `restorePassword` RPC → password is set. **UI changes** (`Password.svelte`): - `hasPassword === false` → "Set a password" panel with description and "Send setup link" button - On success → "Check your email for a link to set your password." - On `SocialIdNotFound` → "No email address is linked to your account." with guidance to add one via Account Settings → Manage Identities - `hasPassword === true` → existing "Change password" form (unchanged) **Account client:** Added `checkHasPassword()` and `requestPasswordSetup()` methods to `AccountClientImpl`; both registered as platform resource functions (`login.function.CheckHasPassword` / `login.function.RequestPasswordSetup`). Signed-off-by: Don Kendall <dkendall@ledoweb.com> Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Signed-off-by: Don Kendall <kendall@donkendall.com> * test(password): add unit tests for SSO password setup RPCs ssoPassword.test.ts — 12 tests covering: - checkHasPassword: returns true/false for hash+salt presence, false for partial state (hash-only or salt-only), error for missing account - changePassword: rejects empty old/new passwords, rejects wrong oldPassword (hash mismatch) - requestPasswordSetup: sends email when email social ID exists, returns SocialIdNotFound when no email is linked, handles mail service failures gracefully (logs error, does not rethrow) signupTokenGuard.test.ts — added edge-case for empty-string token to document current guard behaviour (token != null passes empty string through; noted as a future hardening opportunity). Signed-off-by: Don Kendall <dkendall@ledoweb.com> Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Signed-off-by: Don Kendall <kendall@donkendall.com> * chore(dev): add dev-local webpack proxy for local Docker compose stack Adds a `dev-local` CLIENT_TYPE that proxies webpack dev server requests to a local Docker compose stack (nginx at localhost:8088), following the same pattern as the existing `dev-server`, `dev-huly`, etc. modes. Useful for developing frontend changes against a fully running local backend without needing `huly.local` DNS configuration. Signed-off-by: Don Kendall <dkendall@ledoweb.com> Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Signed-off-by: Don Kendall <kendall@donkendall.com> * feat(email): redesign transactional emails with proper HTML and dedicated password setup template All account service email templates were bare <p> tags with no styling, branding, or call-to-action buttons. Replaced with production-quality HTML emails using email-safe table layout and inline CSS. Design: Huly wordmark on dark (#18181B) header, white card body, dark CTA button, subtle border, system font stack. Plain-text versions updated to match for clients that prefer text. Templates improved: - RecoveryHTML/Text — password reset flow - ConfirmationHTML/Text — email verification on signup - InviteHTML/Text — workspace invitation - ResendInviteHTML/Text — re-invitation - OtpHTML/Text — sign-in code with large monospace code display New dedicated template for SSO password setup (PasswordSetupHTML/Text/ Subject) so the setup email has copy distinct from forgot-password recovery. requestPasswordSetup now uses these instead of RecoveryHTML. Subject: "Set a password for your Huly account". Other language files updated with the new PasswordSetup* keys (English copy as fallback — translations can follow separately). Signed-off-by: Don Kendall <dkendall@ledoweb.com> Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Signed-off-by: Don Kendall <kendall@donkendall.com> * fix(password): guard requestPasswordSetup against accounts with existing password Add server-side check that rejects requestPasswordSetup calls from accounts that already have a password hash+salt. The setup flow bypasses the old-password requirement in changePassword, so it must be restricted to SSO-only accounts. The UI already guards this branch but defence-in-depth requires the server to enforce it independently. Also adds JSDoc to requestPasswordSetup and extends unit test coverage: - TokenError path for checkHasPassword (invalid/expired token) - BadRequest guard for requestPasswordSetup on password-bearing accounts Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Signed-off-by: Don Kendall <kendall@donkendall.com> * fix: add missing locale keys and fix eslint/formatting for CI - Add 5 missing SSO password translation keys to all non-en locale files (SetPassword, SSOPasswordDescription, SendSetupLink, SSOPasswordEmailSent, SSONoEmailLinked) to fix locale parity test - Replace non-null assertions with type casts in ssoPassword.test.ts to fix @typescript-eslint/no-non-null-assertion errors - Revert unrelated tracker/github cosmetic changes that triggered pre-existing eslint errors in those packages Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Signed-off-by: Don Kendall <kendall@donkendall.com> * fix: address review — remove dev/prod changes, translate PasswordSetup strings - Revert dev/prod/webpack.config.js and package.json (per BykhovDenis) - Translate PasswordSetupText and PasswordSetupSubject for all 10 locales (cs, de, es, fr, it, pt-br, pt, ru, tr, zh) - PasswordSetupHTML stays in English (reviewer approved) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Signed-off-by: Don Kendall <kendall@donkendall.com> --------- Signed-off-by: Don Kendall <dkendall@ledoweb.com> Signed-off-by: Don Kendall <kendall@donkendall.com> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>