[pull] master from mattermost:master#752
Merged
Merged
Conversation
* [MM-69026] Add zoom and pan to the image file preview Enables the existing file-preview-modal zoom controls for image previews (previously PDF-only) and adds cursor-aware wheel zoom, drag-to-pan, keyboard shortcuts, and overflow clipping so the panned image can't escape behind the modal header. - Per-file default scale (1.0 for images, 1.75 stays for PDFs). - Translate state alongside scale; auto-snaps to the origin at default scale. - Native non-passive wheel listener so preventDefault actually fires. - Wheel step scaled by deltaY magnitude for trackpad pinch. - Keyboard: +/=, -, 0; skipped when an input/textarea/contentEditable is focused. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * Fix eslint no-mixed-operators and lines-around-comment Parenthesise mixed +/* and -/ arithmetic to satisfy eslint(no-mixed-operators) and add the blank line before the inline-input guard comment for lines-around-comment. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * Cap image zoom at 2x and harden lifecycle / drag-pan - Add ZoomSettings.MAX_SCALE_IMAGE = 2.0 and route image-path clamp sites through a new FilePreviewModal.getMaxScaleForFile. PDFs keep the original 3.0 ceiling. - Reconcile scale/translate in getDerivedStateFromProps when props.fileInfos changes so newly appearing indexes get seeded with the file's default instead of reading as undefined. - Gate drag-to-pan on currentScale > defaultScale so dragging at default scale (image fits the viewport) doesn't slide the image around in empty space. - Tighten the e2e style-match regex so it only accepts scale values strictly greater than 1. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * Reset image zoom state on same-length file swaps A websocket post update can replace an attachment at the same index without changing the array length, which previously bypassed the length-based reconciliation in getDerivedStateFromProps and let the old file's zoom/translate state apply to the new file. Track a per-index identity (file id, falling back to link) and trigger the same reconciliation when any identity differs at its index; indexes whose identity is unchanged keep their existing scale/translate. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * Add unit tests for zoom-related instance behavior and helpers Covers the gaps flagged by Tests/analysis: - Static helpers getDefaultScaleForFile, getMaxScaleForFile, and getFileIdentity (incl. namespace separation for file vs link identities). - handleKeyDown: +/= zoom in, - zoom out, 0 reset, modifier-key bailout, and the INPUT-focus guard. - handleImageMouseDown drag gate: ignored at default scale and on non-left-button mousedowns; sets isDragging when zoomed. - handleImageWheel clamping at MAX_SCALE_IMAGE (2.0) and MIN_SCALE (0.25), plus deltaY=0 short-circuit. - getDerivedStateFromProps identity reconciliation: same-length swap resets the affected index while preserving others; list growth seeds the new index with the file's default. 68 tests pass (was 50). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ngs (#36706) * MM-68417, MM-68420: API support for PAT expiry and admin policy settings POST /users/{id}/tokens now accepts a client-supplied expires_at (previously stripped per the TODO in api4/user.go), and the create app method enforces two new ServiceSettings: - EnforcePersonalAccessTokenExpiry (bool, default false): when on, rejects creates with expires_at == 0 - MaximumPersonalAccessTokenLifetimeDays (int, default 0 = unlimited): caps how far in the future expires_at may be Rejections return distinct app error ids so clients can disambiguate: expires_at_required, expires_at_in_past, expires_at_too_far. GET /users/{id}/tokens already serializes expires_at via the model's JSON tag added in MM-68419; clients derive token status (active / expired / inactive) from is_active + expires_at without a separate server-side field, keeping the response shape minimal. The Client4 helper CreateUserAccessToken gained an optional variadic expiresAt parameter (and the mmctl Client interface + mock match) rather than introducing a parallel WithExpiry method. Refs: MM-68417, MM-68420 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * MM-68417: exempt bot accounts from PAT expiry enforcement Mirrors the existing EnableUserAccessTokens bypass at session.go:453, where bot tokens are allowed even when human PATs are disabled. Bots are programmatic clients that typically need long-lived credentials, and integrations that provision them would otherwise break the moment an admin enables EnforcePersonalAccessTokenExpiry — turning a settings toggle into a footgun. The expiry policy now applies only to human users; bots can still be given a future expires_at by callers that want it, but the server won't require one. Locked in by a new TestCreateUserAccessToken/bot_tokens_are_exempt subtest that enables enforcement plus a 30-day cap, creates a bot, and asserts a non-expiring token is accepted. Refs: MM-68417 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * MM-68420: bound MaximumPersonalAccessTokenLifetimeDays in isValid Negative values silently meant "unlimited" (the runtime check is `> 0`), and very large values overflow int64 when computing `now + days*86_400_000` at token-creation time, producing a wrap-around that either rejects all reasonable expiries or accepts past timestamps as valid. Bound the setting in ServiceSettings.isValid to [0, MaxPersonalAccess TokenLifetimeDays] where the cap is 36500 (100 years) — past any realistic operational use and well clear of int64 overflow. Surfaces as a config validation error rather than a silently-broken runtime check. New TestServiceSettingsIsValid cases lock in zero, negative, upper-bound, and above-upper-bound behavior. Refs: MM-68420 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * MM-68417: reject multiple expiresAt values in Client4 helper CodeRabbit caught that the variadic CreateUserAccessToken silently used expiresAt[0] when callers passed more than one value, masking a mis-call instead of failing fast. Return an error in that case so the misuse is visible at the call site rather than producing a token with the wrong (or right-but-coincidental) expiry. Refs: MM-68417 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * MM-68417: make expiresAt a required parameter on Client4.CreateUserAccessToken Drop the variadic in favor of a regular int64 parameter. The variadic form silently dropped extra values and made a misuse undetectable at the call site (per CodeRabbit review on PR 36706); the previous fix guarded against >1 values at runtime, but a required parameter is strictly better — the compiler now refuses the misuse and every caller is forced to make a deliberate decision about expiry. Existing callers that want the old behavior pass 0 (== never expires). Refs: MM-68417 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * MM-68417: add --expires-in flag to mmctl user token generate Adds an --expires-in duration flag so operators can create expiring PATs via the CLI. Accepts the standard Go duration syntax plus a trailing 'd' for days (the common case for token lifetimes), e.g. --expires-in 90d, --expires-in 12h, --expires-in 1h30m. Empty (the default) means no expiry — matching prior behavior. Without this flag the command was unusable once an admin enables EnforcePersonalAccessTokenExpiry, since every create would fail with app.user_access_token.expires_at_required.app_error. Flag parsing now happens before the user-lookup API call so the command fails fast on invalid input. Regenerated mmctl docs reflect the new flag. Refs: MM-68417 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * MM-68417: cap --expires-in day count to prevent time.Duration overflow parseExpiresIn returns time.Duration(days) * 24 * time.Hour, which is int64 nanoseconds and overflows past ~106751 days (CodeRabbit caught this). Cap at model.MaxPersonalAccessTokenLifetimeDays (36500) so the CLI rejects values the server would reject anyway, well below the int64-overflow point. Adds two test cases (at-cap and beyond-cap) to TestParseExpiresIn. Refs: MM-68417 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * MM-68420: collapse PAT expiry settings into a single max-lifetime setting Remove ServiceSettings.EnforcePersonalAccessTokenExpiry and fold the policy onto MaximumPersonalAccessTokenLifetimeDays: 0 means no policy (never-expiring tokens allowed, no cap), while a value > 0 requires every new token to expire within that many days. The two-setting design let an admin set a maximum but leave enforcement off, silently allowing never-expiring tokens to sidestep the cap; the only combination the boolean added (require expiry, no upper bound) has little practical value. The removed field was introduced on this branch and never released, so this is not a breaking change. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
See Commits and Changes for more details.
Created by
pull[bot] (v2.0.0-alpha.4)
Can you help keep this open source service alive? 💖 Please sponsor : )