Files
outline/shared/validations.ts
Copilot 7ed41eadc6 Add per-share branding: title and logoUrl overrides (#12003)
* feat: add title and logoUrl to Share model

Agent-Logs-Url: https://github.com/outline/outline/sessions/9bc9d438-6892-4903-9d32-6b6868f4fd97

Co-authored-by: tommoor <380914+tommoor@users.noreply.github.com>

* fix: use STRING(4096) for logoUrl column in migration

Agent-Logs-Url: https://github.com/outline/outline/sessions/9bc9d438-6892-4903-9d32-6b6868f4fd97

Co-authored-by: tommoor <380914+tommoor@users.noreply.github.com>

* feat: use share title and logoUrl to override team branding on shared page

Agent-Logs-Url: https://github.com/outline/outline/sessions/854d6d22-e80b-4673-b3b2-0f9cf43a3246

Co-authored-by: tommoor <380914+tommoor@users.noreply.github.com>

* refactor: use ShareValidation class constants for title/logoUrl max lengths

Agent-Logs-Url: https://github.com/outline/outline/sessions/ea462d6a-d4d3-4882-ab8e-88060bf64877

Co-authored-by: tommoor <380914+tommoor@users.noreply.github.com>

* fix: use ShareValidation constants in @Length msg template literals

Agent-Logs-Url: https://github.com/outline/outline/sessions/694116c2-47e8-4001-a103-c8a62c7ac71e

Co-authored-by: tommoor <380914+tommoor@users.noreply.github.com>

* feat: add display settings popover with custom title and icon for shares

Move share toggles (search indexing, email subscriptions, show last
modified, show TOC) into a popover triggered by a settings cog. The
popover also includes inputs for a custom site title and icon upload
to override team branding on shared pages. Rename logoUrl to iconUrl,
loosen URL validation to allow relative attachment paths, and surface
the popover in the shared page header for users with edit permission.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* styling

* Display branding on single shared pages

* Review comments

* refactor

* PR feedback

* Lose 'Remove icon' button

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: tommoor <380914+tommoor@users.noreply.github.com>
Co-authored-by: Tom Moor <tom@getoutline.com>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-26 21:23:13 -04:00

182 lines
4.5 KiB
TypeScript

export const AttachmentValidation = {
/** The limited allowable mime-types for user and team avatars */
avatarContentTypes: ["image/jpg", "image/jpeg", "image/png"],
/** The most widely supported mime-types across modern browsers */
emojiContentTypes: [
"image/png",
"image/webp",
"image/gif",
"image/jpeg",
"image/jpg",
],
/** The maximum file size for emoji uploads */
emojiMaxFileSize: 1 * 1000 * 1000,
/** Image mime-types commonly supported by modern browsers */
imageContentTypes: [
"image/jpg",
"image/jpeg",
"image/pjpeg",
"image/png",
"image/apng",
"image/avif",
"image/gif",
"image/webp",
"image/svg",
"image/svg+xml",
"image/bmp",
"image/tiff",
"image/heic",
],
};
export const ApiKeyValidation = {
/** The minimum length of the API key name */
minNameLength: 3,
/** The maximum length of the API key name */
maxNameLength: 255,
};
export const CollectionValidation = {
/** The maximum length of the collection description */
maxDescriptionLength: 100 * 1000,
/** The maximum length of the collection name */
maxNameLength: 100,
};
export const CommentValidation = {
/** The maximum length of a comment */
maxLength: 1000,
};
export const DocumentValidation = {
/** The maximum length of the document title */
maxTitleLength: 100,
/** The maximum length of the document summary */
maxSummaryLength: 1000,
/** The maximum size of the collaborative document state */
maxStateLength: 1500 * 1024,
/** The maximum recommended size of the document content */
maxRecommendedLength: 250000,
};
export const GroupValidation = {
/** The maximum length of the group name */
maxNameLength: 255,
/** The maximum length of the group description */
maxDescriptionLength: 2000,
};
export const ImportValidation = {
/** The maximum length of the import name */
maxNameLength: 100,
};
export const OAuthClientValidation = {
/** The maximum length of the OAuth client name */
maxNameLength: 100,
/** The maximum length of the OAuth client description */
maxDescriptionLength: 255,
/** The maximum length of the OAuth client developer name */
maxDeveloperNameLength: 100,
/** The maximum length of the OAuth client developer URL */
maxDeveloperUrlLength: 255,
/** The maximum length of the OAuth client avatar URL */
maxAvatarUrlLength: 255,
/** The maximum length of an OAuth client redirect URI */
maxRedirectUriLength: 255,
/** The allowed OAuth client types */
clientTypes: ["confidential", "public"] as const,
};
export const ShareValidation = {
/** The maximum length of the share title */
maxTitleLength: 255,
/** The maximum length of the share iconUrl */
maxIconUrlLength: 4096,
};
export const RevisionValidation = {
minNameLength: 1,
maxNameLength: 255,
};
export const UserPasskeyValidation = {
minNameLength: 1,
maxNameLength: 255,
};
export const PinValidation = {
/** The maximum number of pinned documents on an individual collection or home screen */
max: 8,
};
export const TeamValidation = {
/** The maximum number of domains per team on cloud hosted */
maxDomains: 10,
/** The maximum length of the team name */
maxNameLength: 255,
/** The maximum length of the team description */
maxDescriptionLength: 1000,
/** The minimum length of the team subdomain */
minSubdomainLength: 2,
/** The maximum length of the team subdomain for cloud */
maxSubdomainLength: 32,
/** The maximum length of the team subdomain for self-hosted */
maxSubdomainSelfHostedLength: 255,
/** The maximum length of a team domain */
maxDomainLength: 255,
/** The maximum length of MCP workspace guidance */
maxGuidanceMCPLength: 10000,
/** The recommended length of MCP workspace guidance, beyond which a warning is shown */
warnGuidanceMCPLength: 2000,
};
export const UserValidation = {
/** The maximum number of invites per request */
maxInvitesPerRequest: 20,
/** The maximum length of the user name */
maxNameLength: 255,
/** The maximum length of the user email */
maxEmailLength: 255,
};
export const WebhookSubscriptionValidation = {
/** The maximum number of webhooks per team */
maxSubscriptions: 10,
/** The maximum length of the webhook name */
maxNameLength: 255,
/** The maximum length of the webhook url */
maxUrlLength: 255,
};
export const EmojiValidation = {
/** The maximum length of the emoji name */
maxNameLength: 25,
/* the characters allowed in the name */
allowedNameCharacters: /^[a-z0-9_]*$/,
};