Commit Graph
4748 Commits
Author SHA1 Message Date
Denis Bykhov 71834690ad Transform process action
Signed-off-by: Denis Bykhov <bykhov.denis@gmail.com>
2026-03-23 03:49:33 +05:00
db2fb631f8 fix(view): "Not Specified" group shows assigned issues (#10606) (#10666)
When grouping by assignee with a secondary grouping (e.g. by Status),
the "Not Specified" category passed `undefined` as the query value.
Since `undefined` is stripped during JSON serialization, the server
received no filter and returned all documents — causing assigned
issues to appear under "Not Specified".

Use `null` instead so the filter survives serialization and correctly
matches only documents where the field is unset.

Fixes #10606

Signed-off-by: Don Kendall <kendall@donkendall.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 12:04:23 +07:00
Denis BykhovandGitHub c800a95b50 Implement persistent table sorting by integrating with view options. (#10665)
Signed-off-by: Denis Bykhov <bykhov.denis@gmail.com>
2026-03-22 10:30:54 +07:00
Denis BykhovandGitHub 4ef554b9d2 Two-Factor Authentication (2FA) (#10658)
* Two-Factor Authentication (2FA)

Signed-off-by: Denis Bykhov <bykhov.denis@gmail.com>

* Fix test

Signed-off-by: Denis Bykhov <bykhov.denis@gmail.com>

* Fix test

Signed-off-by: Denis Bykhov <bykhov.denis@gmail.com>

* Fix tests

Signed-off-by: Denis Bykhov <bykhov.denis@gmail.com>

* More test fixes

Signed-off-by: Denis Bykhov <bykhov.denis@gmail.com>

* Fix tests

Signed-off-by: Denis Bykhov <bykhov.denis@gmail.com>

---------

Signed-off-by: Denis Bykhov <bykhov.denis@gmail.com>
2026-03-21 14:36:32 +07:00
f44d88e134 feat(password): email-confirmed password setup for SSO accounts (#10649)
* 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>
2026-03-21 03:53:18 +05:00
Artyom SavchenkoandGitHub 982527a364 Allow to add social links if there are no attached messages (#10657)
Signed-off-by: Artem Savchenko <armisav@gmail.com>
2026-03-20 17:18:45 +07:00
Artyom SavchenkoandGitHub 9bbbc609fc Fix social link save (#10655)
Signed-off-by: Artem Savchenko <armisav@gmail.com>
2026-03-20 17:18:32 +07:00
Artyom SavchenkoandGitHub c3f9cd04ac Fix intermittent PDF print failures (#10654)
Signed-off-by: Artem Savchenko <armisav@gmail.com>
2026-03-19 15:55:46 +07:00
b426a42a4f fix(login): guard logIn() behind token check in password signup (#10518) (#10650)
When MAIL_URL is configured the account service intentionally returns
token: undefined to enforce email confirmation before granting access.
SignupForm.svelte was calling logIn() unconditionally, which triggered
PUT /cookie with no Authorization header. The cookie endpoint returned
a 401 whose response body was not parseable as JSON, crashing the client
with "Unexpected token 'N', 'Not Found' is not valid JSON". The account
was created successfully but the user was stuck on the signup page.

- Guard logIn() with `result.token != null`, matching the pattern
  already used in doLoginNavigate() in utils.ts
- Fix PUT /cookie 401 response to use ctx.res.writeHead + ctx.res.end
  with the JSON body inline, consistent with the rest of the file.
  Previously ctx.body was set (Koa pattern) then ctx.res.end() was
  called with no body (raw Node pattern), so the body was never sent.
- Add unit tests for the token guard logic

Fixes #10518

Signed-off-by: Don Kendall <kendall@donkendall.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 14:48:29 +07:00
Artyom SavchenkoandGitHub 195d7dbff2 Reuse default invite settings in link generation (#10651)
* Reuse default invite settings in link generation

Signed-off-by: Artem Savchenko <armisav@gmail.com>

* Clean up

Signed-off-by: Artem Savchenko <armisav@gmail.com>

* Capability check

Signed-off-by: Artem Savchenko <armisav@gmail.com>

* Fix warning

Signed-off-by: Artem Savchenko <armisav@gmail.com>

---------

Signed-off-by: Artem Savchenko <armisav@gmail.com>
2026-03-19 14:35:06 +07:00
Artyom SavchenkoandGitHub dc9744ba12 Fix social ID owner check (#10653)
Signed-off-by: Artem Savchenko <armisav@gmail.com>
2026-03-19 14:34:48 +07:00
Niels KaspersandGitHub de5de3d2ce fix(tracker): truncate long milestone titles on issue cards (#10646)
* fix(tracker): truncate long milestone titles on issue cards (#9655)

Signed-off-by: Niels Kaspers <kaspersniels@gmail.com>

* style: fix formatting in MilestoneEditor.svelte

Break long div attributes onto separate lines per prettier config.

---------

Signed-off-by: Niels Kaspers <kaspersniels@gmail.com>
2026-03-19 11:10:36 +07:00
2d26c74874 feat(text-editor): add highlight, subscript, superscript and mathematics toolbar actions (#10627)
* feat(text-editor): add highlight action

Signed-off-by: ComputerCrack <github.compacter838@simplelogin.com>

* feat(text-editor): add subscript and superscript actions

Signed-off-by: ComputerCrack <github.compacter838@simplelogin.com>

* feat(text-editor): add mathematics inline and block actions

Signed-off-by: ComputerCrack <github.compacter838@simplelogin.com>

* chore(text-editor): add mathematics and katex dependencies

Signed-off-by: ComputerCrack <github.compacter838@simplelogin.com>

* fix(text-editor): fix eslint strict-boolean-expressions in mathematics extension

Signed-off-by: ComputerCrack <github.compacter838@simplelogin.com>

* fix(text-editor): change max-width of toolbar to display all icons correctly

Signed-off-by: ComputerCrack <github.compacter838@simplelogin.com>

* chore(text-editor): add subscript and superscript as direct dependencies

Signed-off-by: ComputerCrack <github.compacter838@simplelogin.com>

* chore(text-editor): add missing locale keys for new text editor actions [temp, AI-generated]

Adds placeholder translations (English fallback) for Highlight, Subscript,  Superscript, Mathematics, and MathematicsBlock to all non-English locale files. Translations are not reviewed and should be replaced by a native speaker.

Signed-off-by: ComputerCrack <github.compacter838@simplelogin.com>

* fix(text-editor): fix subscript/superscript serialization and extension placement

Signed-off-by: ComputerCrack <github.compacter838@simplelogin.com>

---------

Signed-off-by: ComputerCrack <github.compacter838@simplelogin.com>
Co-authored-by: ComputerCrack <github.compacter838@simplelogin.com>
2026-03-19 09:51:24 +07:00
Artyom SavchenkoandGitHub 83fdb49d23 Fix export translations (#10652)
Signed-off-by: Artem Savchenko <armisav@gmail.com>
2026-03-19 09:46:53 +07:00
Denis BykhovandGitHub f08d157125 Fix request section visibility and hide card activity for guests (#10641)
* move RequestsCardSection visibility check into the component.

Signed-off-by: Denis Bykhov <bykhov.denis@gmail.com>

* Hide card activity for guests

Signed-off-by: Denis Bykhov <bykhov.denis@gmail.com>

* Fix formatting

Signed-off-by: Denis Bykhov <bykhov.denis@gmail.com>

---------

Signed-off-by: Denis Bykhov <bykhov.denis@gmail.com>
2026-03-16 21:31:41 +07:00
Denis BykhovandGitHub 662fe5265a Reset id (#10643)
Signed-off-by: Denis Bykhov <bykhov.denis@gmail.com>
2026-03-16 21:31:08 +07:00
Artyom SavchenkoandGitHub c0d9f64f8d Load RefTo fields in markdown table (#10642)
* Load RefTo fields in markdown table

Signed-off-by: Artem Savchenko <armisav@gmail.com>

* Fix Polynomial regexp

Signed-off-by: Artem Savchenko <armisav@gmail.com>

* Fix formatting

Signed-off-by: Artem Savchenko <armisav@gmail.com>

---------

Signed-off-by: Artem Savchenko <armisav@gmail.com>
2026-03-16 20:00:58 +07:00
Artyom SavchenkoandGitHub f7256a44b4 User should be able to see only own training results (#10629)
Signed-off-by: Artem Savchenko <armisav@gmail.com>
2026-03-12 21:18:03 +07:00
Artyom SavchenkoandGitHub 8a3269248d Make issues read-only for guests (#10595)
* Make issues read-only for guests

Signed-off-by: Artem Savchenko <armisav@gmail.com>

* Fix validation

Signed-off-by: Artem Savchenko <armisav@gmail.com>

---------

Signed-off-by: Artem Savchenko <armisav@gmail.com>
2026-03-12 14:01:42 +07:00
4215717e1d fix(tracker): parentIssue prop overrides draft when reopening create issue modal (#10616)
* fix(tracker): parentIssue prop overrides draft when reopening create issue modal

When creating a sub-task, dismissing the modal via backdrop saves a
draft including the parentIssue. On the next open (for a different
parent), getDefaultObjectFromDraft() spreads the saved draft first but
all explicit props (status, priority, assignee, component, milestone)
correctly override the draft values. parentIssue was the only prop not
included in that override list, so the draft's stale parentIssue always
won, attaching the new sub-task to the previously opened parent.

Added parentIssue to the override spread so an explicitly passed parent
always takes precedence over any saved draft value.

Fixes #10348

Signed-off-by: SaiVaraprasad Medapati <varaprasadreddy9676@gmail.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(tracker): drop stale SubIssues import change

Signed-off-by: SaiVaraprasad Medapati <varaprasadreddy9676@gmail.com>

---------

Signed-off-by: SaiVaraprasad Medapati <varaprasadreddy9676@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-12 12:52:33 +07:00
SaiVaraprasad MedapatiandGitHub d7cde12607 feat(notification): add inbox settings keyboard shortcuts (#10614)
Signed-off-by: SaiVaraprasad Medapati <varaprasadreddy9676@gmail.com>
2026-03-11 12:52:28 +07:00
SaiVaraprasad MedapatiandGitHub a4a6607e22 feat(communication): improve messages loading state accessibility (#10613)
Signed-off-by: SaiVaraprasad Medapati <varaprasadreddy9676@gmail.com>
2026-03-11 12:51:55 +07:00
SaiVaraprasad MedapatiandGitHub eba425ea29 feat(notification): improve inbox list keyboard navigation and a11y (#10612)
Signed-off-by: SaiVaraprasad Medapati <varaprasadreddy9676@gmail.com>
2026-03-11 12:51:23 +07:00
Artyom SavchenkoandGitHub 96ac74078b Fix svelte error in sub-issues (#10618)
* Fix svelte error in sub-issues

Signed-off-by: Artem Savchenko <armisav@gmail.com>

* Check array

Signed-off-by: Artem Savchenko <armisav@gmail.com>

---------

Signed-off-by: Artem Savchenko <armisav@gmail.com>
2026-03-10 21:00:23 +07:00
Denis Bykhov 81cf17ab5d Hide child section for card
Signed-off-by: Denis Bykhov <bykhov.denis@gmail.com>
2026-03-10 12:38:37 +05:00
Igor LoskutovandGitHub badeb2ebd9 fix(tracker): make Project.defaultIssueStatus optional (#10598)
defaultIssueStatus is not reliably populated for all projects.Make the field optional in the type definition and guard the
  migration to handle undefined values.

Signed-off-by: Igor Loskutov <igor.loskutoff@gmail.com>
2026-03-10 11:02:58 +07:00
Artyom SavchenkoandGitHub cad04875f7 Add notifications for reviewed documents (#10601)
* Send notification when document reviewed

Signed-off-by: Artem Savchenko <armisav@gmail.com>

* Clean up

Signed-off-by: Artem Savchenko <armisav@gmail.com>

---------

Signed-off-by: Artem Savchenko <armisav@gmail.com>
2026-03-10 10:25:46 +07:00
Denis BykhovandGitHub eb3317b1fd My cards (#10604)
Signed-off-by: Denis Bykhov <bykhov.denis@gmail.com>
2026-03-10 10:24:21 +07:00
Denis BykhovandGitHub e8c0f8ef4d Fix exporter (#10583)
* Fix exporter

Signed-off-by: Denis Bykhov <bykhov.denis@gmail.com>

* Fix formatting

Signed-off-by: Denis Bykhov <bykhov.denis@gmail.com>

---------

Signed-off-by: Denis Bykhov <bykhov.denis@gmail.com>
2026-03-09 21:14:13 +07:00
Artyom SavchenkoandGitHub 5613b4f708 Fix npm packages to not use legacy repository format (#10576)
* Fix packages script

Signed-off-by: Artem Savchenko <armisav@gmail.com>

* Fix npm packages to not use legacy string repo

Signed-off-by: Artem Savchenko <armisav@gmail.com>

---------

Signed-off-by: Artem Savchenko <armisav@gmail.com>
2026-03-06 12:25:21 +07:00
Artyom SavchenkoandGitHub 7a7020292b Add action to export project documents (#10592)
Signed-off-by: Artem Savchenko <armisav@gmail.com>
2026-03-06 12:24:47 +07:00
Artyom SavchenkoandGitHub f94d564ec6 Support default invite setting in branding (#10591)
Signed-off-by: Artem Savchenko <armisav@gmail.com>
2026-03-05 15:19:43 +07:00
Artyom SavchenkoandGitHub b7b5f5cbe0 Handle no documents to export (#10588)
* Handle no documents to export

Signed-off-by: Artem Savchenko <armisav@gmail.com>

* Fix formatting

Signed-off-by: Artem Savchenko <armisav@gmail.com>

---------

Signed-off-by: Artem Savchenko <armisav@gmail.com>
2026-03-05 15:19:29 +07:00
Artyom SavchenkoandGitHub 6bd7da2c4a Export product version with controlled docs (#10586)
* Export product version with controlled docs

Signed-off-by: Artem Savchenko <armisav@gmail.com>

* Fix tests

Signed-off-by: Artem Savchenko <armisav@gmail.com>

---------

Signed-off-by: Artem Savchenko <armisav@gmail.com>
2026-03-04 14:48:33 +07:00
Artyom SavchenkoandGitHub bfb3c6e81b Give controlled documents access for external approval (#10581)
Signed-off-by: Artem Savchenko <armisav@gmail.com>
2026-03-02 20:12:58 +07:00
Alexander OnnikovandGitHub 58295e4169 feat: auto generate rank in middleware (#10577)
Signed-off-by: Alexander Onnikov <Alexander.Onnikov@xored.com>
2026-03-02 19:18:11 +07:00
Artyom SavchenkoandGitHub 6e7c2496b1 Fix LockFieldEditor.svelte formatting (#10578)
Signed-off-by: Artem Savchenko <armisav@gmail.com>
2026-03-02 12:05:10 +07:00
Denis BykhovandGitHub e778a2748b feat: implement field locking and unlocking functionality, including UI, backend logic, and i18n. (#10573)
Signed-off-by: Denis Bykhov <bykhov.denis@gmail.com>
2026-03-01 00:42:00 +05:00
Denis BykhovandGitHub 33d8d500f3 feat: Implement FieldChangedRollback to revert document updates in … (#10572)
Signed-off-by: Denis Bykhov <bykhov.denis@gmail.com>
2026-03-01 00:41:19 +05:00
Denis BykhovandGitHub c1b8e77e16 Fix process (#10571)
Signed-off-by: Denis Bykhov <bykhov.denis@gmail.com>
2026-02-28 20:11:26 +05:00
Denis BykhovandGitHub 7ab3c00fa5 Fix prrocess user input (#10570)
Signed-off-by: Denis Bykhov <bykhov.denis@gmail.com>
2026-02-28 11:51:22 +05:00
Denis BykhovandGitHub 49318c17cf Fix process middleware (#10568)
Signed-off-by: Denis Bykhov <bykhov.denis@gmail.com>
2026-02-27 14:32:35 +05:00
Artyom SavchenkoandGitHub 0e9bd7db17 Hide other people's social identities (#10566)
Signed-off-by: Artem Savchenko <armisav@gmail.com>
2026-02-27 13:25:18 +05:00
Denis BykhovandGitHub 5752b827d5 Action types for approval requests, enable field synchronization for … (#10565)
Signed-off-by: Denis Bykhov <bykhov.denis@gmail.com>
2026-02-27 05:31:05 +05:00
Artyom SavchenkoandGitHub d7a0fa8309 Do not allow kick last owner (#10559)
Signed-off-by: Artem Savchenko <armisav@gmail.com>
2026-02-26 14:55:17 +05:00
Artyom SavchenkoandGitHub dc964de99f Add tags to markdown table (#10560)
* Add tags to markdown table

Signed-off-by: Artem Savchenko <armisav@gmail.com>

* Clean up

Signed-off-by: Artem Savchenko <armisav@gmail.com>

---------

Signed-off-by: Artem Savchenko <armisav@gmail.com>
2026-02-26 14:46:34 +05:00
Denis BykhovandGitHub b116e711f8 Add tag process fixes (#10561)
Signed-off-by: Denis Bykhov <bykhov.denis@gmail.com>
2026-02-26 14:46:19 +05:00
Artyom SavchenkoandGitHub c68076ea10 Fix last messages button (#10558)
Signed-off-by: Artem Savchenko <armisav@gmail.com>
2026-02-26 09:17:27 +07:00
Artyom SavchenkoandGitHub 48a28a0b81 Configure who should be able to send invitation link (#10555)
* Configure who should be able to send invitation link

Signed-off-by: Artem Savchenko <armisav@gmail.com>

* Add user role select

Signed-off-by: Artem Savchenko <armisav@gmail.com>

* Limit default user roles

Signed-off-by: Artem Savchenko <armisav@gmail.com>

---------

Signed-off-by: Artem Savchenko <armisav@gmail.com>
2026-02-25 19:42:11 +07:00
Denis BykhovandGitHub 6030f921c8 Fix missing enum when export type (#10551)
Signed-off-by: Denis Bykhov <bykhov.denis@gmail.com>
2026-02-25 10:23:29 +07:00