mirror of
https://github.com/documenso/documenso.git
synced 2025-11-20 11:41:44 +10:00
Merge branch 'main' into feat/signing-reminders
This commit is contained in:
@ -12,3 +12,5 @@ export const NEXT_PRIVATE_INTERNAL_WEBAPP_URL =
|
||||
export const IS_BILLING_ENABLED = () => env('NEXT_PUBLIC_FEATURE_BILLING_ENABLED') === 'true';
|
||||
|
||||
export const API_V2_BETA_URL = '/api/v2-beta';
|
||||
|
||||
export const SUPPORT_EMAIL = env('NEXT_PUBLIC_SUPPORT_EMAIL') ?? 'support@documenso.com';
|
||||
|
||||
@ -31,6 +31,7 @@ export const USER_SECURITY_AUDIT_LOG_MAP: Record<string, string> = {
|
||||
PASSKEY_UPDATED: 'Passkey updated',
|
||||
PASSWORD_RESET: 'Password reset',
|
||||
PASSWORD_UPDATE: 'Password updated',
|
||||
SESSION_REVOKED: 'Session revoked',
|
||||
SIGN_OUT: 'Signed Out',
|
||||
SIGN_IN: 'Signed In',
|
||||
SIGN_IN_FAIL: 'Sign in attempt failed',
|
||||
|
||||
8
packages/lib/constants/autosign.ts
Normal file
8
packages/lib/constants/autosign.ts
Normal file
@ -0,0 +1,8 @@
|
||||
import { FieldType } from '@prisma/client';
|
||||
|
||||
export const AUTO_SIGNABLE_FIELD_TYPES: FieldType[] = [
|
||||
FieldType.NAME,
|
||||
FieldType.INITIALS,
|
||||
FieldType.EMAIL,
|
||||
FieldType.DATE,
|
||||
];
|
||||
@ -1,12 +1,18 @@
|
||||
export enum STRIPE_CUSTOMER_TYPE {
|
||||
INDIVIDUAL = 'individual',
|
||||
TEAM = 'team',
|
||||
}
|
||||
import { SubscriptionStatus } from '@prisma/client';
|
||||
|
||||
export enum STRIPE_PLAN_TYPE {
|
||||
REGULAR = 'regular',
|
||||
TEAM = 'team',
|
||||
COMMUNITY = 'community',
|
||||
FREE = 'free',
|
||||
INDIVIDUAL = 'individual',
|
||||
PRO = 'pro',
|
||||
EARLY_ADOPTER = 'earlyAdopter',
|
||||
PLATFORM = 'platform',
|
||||
ENTERPRISE = 'enterprise',
|
||||
}
|
||||
|
||||
export const FREE_TIER_DOCUMENT_QUOTA = 5;
|
||||
|
||||
export const SUBSCRIPTION_STATUS_MAP = {
|
||||
[SubscriptionStatus.ACTIVE]: 'Active',
|
||||
[SubscriptionStatus.INACTIVE]: 'Inactive',
|
||||
[SubscriptionStatus.PAST_DUE]: 'Past Due',
|
||||
};
|
||||
|
||||
@ -9,6 +9,7 @@ export const VALID_DATE_FORMAT_VALUES = [
|
||||
'yyyy-MM-dd',
|
||||
'dd/MM/yyyy hh:mm a',
|
||||
'MM/dd/yyyy hh:mm a',
|
||||
'dd.MM.yyyy HH:mm',
|
||||
'yyyy-MM-dd HH:mm',
|
||||
'yy-MM-dd hh:mm a',
|
||||
'yyyy-MM-dd HH:mm:ss',
|
||||
@ -17,6 +18,8 @@ export const VALID_DATE_FORMAT_VALUES = [
|
||||
"yyyy-MM-dd'T'HH:mm:ss.SSSXXX",
|
||||
] as const;
|
||||
|
||||
export type ValidDateFormat = (typeof VALID_DATE_FORMAT_VALUES)[number];
|
||||
|
||||
export const DATE_FORMATS = [
|
||||
{
|
||||
key: 'yyyy-MM-dd_hh:mm_a',
|
||||
@ -38,6 +41,11 @@ export const DATE_FORMATS = [
|
||||
label: 'MM/DD/YYYY',
|
||||
value: 'MM/dd/yyyy hh:mm a',
|
||||
},
|
||||
{
|
||||
key: 'DDMMYYYYHHMM',
|
||||
label: 'DD.MM.YYYY HH:mm',
|
||||
value: 'dd.MM.yyyy HH:mm',
|
||||
},
|
||||
{
|
||||
key: 'YYYYMMDDHHmm',
|
||||
label: 'YYYY-MM-DD HH:mm',
|
||||
@ -94,3 +102,7 @@ export const convertToLocalSystemFormat = (
|
||||
|
||||
return formattedDate;
|
||||
};
|
||||
|
||||
export const isValidDateFormat = (dateFormat: unknown): dateFormat is ValidDateFormat => {
|
||||
return VALID_DATE_FORMAT_VALUES.includes(dateFormat as ValidDateFormat);
|
||||
};
|
||||
|
||||
@ -19,6 +19,10 @@ export const DOCUMENT_AUTH_TYPES: Record<string, DocumentAuthTypeData> = {
|
||||
key: DocumentAuth.TWO_FACTOR_AUTH,
|
||||
value: 'Require 2FA',
|
||||
},
|
||||
[DocumentAuth.PASSWORD]: {
|
||||
key: DocumentAuth.PASSWORD,
|
||||
value: 'Require password',
|
||||
},
|
||||
[DocumentAuth.EXPLICIT_NONE]: {
|
||||
key: DocumentAuth.EXPLICIT_NONE,
|
||||
value: 'None (Overrides global settings)',
|
||||
|
||||
@ -2,6 +2,13 @@ import type { MessageDescriptor } from '@lingui/core';
|
||||
import { msg } from '@lingui/core/macro';
|
||||
import { DocumentDistributionMethod, DocumentStatus } from '@prisma/client';
|
||||
|
||||
/**
|
||||
* Workaround for E2E tests to not import `msg`.
|
||||
*/
|
||||
import { DocumentSignatureType } from '@documenso/lib/utils/teams';
|
||||
|
||||
export { DocumentSignatureType };
|
||||
|
||||
export const DOCUMENT_STATUS: {
|
||||
[status in DocumentStatus]: { description: MessageDescriptor };
|
||||
} = {
|
||||
@ -35,12 +42,6 @@ export const DOCUMENT_DISTRIBUTION_METHODS: Record<string, DocumentDistributionM
|
||||
},
|
||||
} satisfies Record<DocumentDistributionMethod, DocumentDistributionMethodTypeData>;
|
||||
|
||||
export enum DocumentSignatureType {
|
||||
DRAW = 'draw',
|
||||
TYPE = 'type',
|
||||
UPLOAD = 'upload',
|
||||
}
|
||||
|
||||
type DocumentSignatureTypeData = {
|
||||
label: MessageDescriptor;
|
||||
value: DocumentSignatureType;
|
||||
@ -48,15 +49,24 @@ type DocumentSignatureTypeData = {
|
||||
|
||||
export const DOCUMENT_SIGNATURE_TYPES = {
|
||||
[DocumentSignatureType.DRAW]: {
|
||||
label: msg`Draw`,
|
||||
label: msg({
|
||||
message: `Draw`,
|
||||
context: `Draw signatute type`,
|
||||
}),
|
||||
value: DocumentSignatureType.DRAW,
|
||||
},
|
||||
[DocumentSignatureType.TYPE]: {
|
||||
label: msg`Type`,
|
||||
label: msg({
|
||||
message: `Type`,
|
||||
context: `Type signatute type`,
|
||||
}),
|
||||
value: DocumentSignatureType.TYPE,
|
||||
},
|
||||
[DocumentSignatureType.UPLOAD]: {
|
||||
label: msg`Upload`,
|
||||
label: msg({
|
||||
message: `Upload`,
|
||||
context: `Upload signatute type`,
|
||||
}),
|
||||
value: DocumentSignatureType.UPLOAD,
|
||||
},
|
||||
} satisfies Record<DocumentSignatureType, DocumentSignatureTypeData>;
|
||||
|
||||
@ -3,6 +3,11 @@ import { env } from '../utils/env';
|
||||
export const FROM_ADDRESS = env('NEXT_PRIVATE_SMTP_FROM_ADDRESS') || 'noreply@documenso.com';
|
||||
export const FROM_NAME = env('NEXT_PRIVATE_SMTP_FROM_NAME') || 'Documenso';
|
||||
|
||||
export const DOCUMENSO_INTERNAL_EMAIL = {
|
||||
name: FROM_NAME,
|
||||
address: FROM_ADDRESS,
|
||||
};
|
||||
|
||||
export const SERVICE_USER_EMAIL = 'serviceaccount@documenso.com';
|
||||
|
||||
export const EMAIL_VERIFICATION_STATE = {
|
||||
|
||||
@ -2,7 +2,6 @@ import { env } from '@documenso/lib/utils/env';
|
||||
|
||||
import { NEXT_PUBLIC_WEBAPP_URL } from './app';
|
||||
|
||||
const NEXT_PUBLIC_FEATURE_BILLING_ENABLED = () => env('NEXT_PUBLIC_FEATURE_BILLING_ENABLED');
|
||||
const NEXT_PUBLIC_POSTHOG_KEY = () => env('NEXT_PUBLIC_POSTHOG_KEY');
|
||||
|
||||
/**
|
||||
@ -10,26 +9,6 @@ const NEXT_PUBLIC_POSTHOG_KEY = () => env('NEXT_PUBLIC_POSTHOG_KEY');
|
||||
*/
|
||||
export const FEATURE_FLAG_GLOBAL_SESSION_RECORDING = 'global_session_recording';
|
||||
|
||||
/**
|
||||
* How frequent to poll for new feature flags in milliseconds.
|
||||
*/
|
||||
export const FEATURE_FLAG_POLL_INTERVAL = 30000;
|
||||
|
||||
/**
|
||||
* Feature flags that will be used when PostHog is disabled.
|
||||
*
|
||||
* Does not take any person or group properties into account.
|
||||
*/
|
||||
export const LOCAL_FEATURE_FLAGS: Record<string, boolean> = {
|
||||
app_allow_encrypted_documents: false,
|
||||
app_billing: NEXT_PUBLIC_FEATURE_BILLING_ENABLED() === 'true',
|
||||
app_document_page_view_history_sheet: false,
|
||||
app_passkey: true,
|
||||
app_public_profile: true,
|
||||
marketing_header_single_player_mode: false,
|
||||
marketing_profiles_announcement_bar: true,
|
||||
} as const;
|
||||
|
||||
/**
|
||||
* Extract the PostHog configuration from the environment.
|
||||
*/
|
||||
@ -46,10 +25,3 @@ export function extractPostHogConfig(): { key: string; host: string } | null {
|
||||
host: postHogHost,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether feature flags are enabled for the current instance.
|
||||
*/
|
||||
export function isFeatureFlagEnabled(): boolean {
|
||||
return extractPostHogConfig() !== null;
|
||||
}
|
||||
|
||||
25
packages/lib/constants/organisations-translations.ts
Normal file
25
packages/lib/constants/organisations-translations.ts
Normal file
@ -0,0 +1,25 @@
|
||||
/**
|
||||
* These constants are in a different file to avoid E2E tests from importing `msg`
|
||||
* which will break it.
|
||||
*/
|
||||
import type { MessageDescriptor } from '@lingui/core';
|
||||
import { msg } from '@lingui/core/macro';
|
||||
import type { OrganisationMemberRole } from '@prisma/client';
|
||||
|
||||
export const ORGANISATION_MEMBER_ROLE_MAP: Record<
|
||||
keyof typeof OrganisationMemberRole,
|
||||
MessageDescriptor
|
||||
> = {
|
||||
ADMIN: msg`Admin`,
|
||||
MANAGER: msg`Manager`,
|
||||
MEMBER: msg`Member`,
|
||||
};
|
||||
|
||||
export const EXTENDED_ORGANISATION_MEMBER_ROLE_MAP: Record<
|
||||
keyof typeof OrganisationMemberRole,
|
||||
MessageDescriptor
|
||||
> = {
|
||||
ADMIN: msg`Organisation Admin`,
|
||||
MANAGER: msg`Organisation Manager`,
|
||||
MEMBER: msg`Organisation Member`,
|
||||
};
|
||||
128
packages/lib/constants/organisations.ts
Normal file
128
packages/lib/constants/organisations.ts
Normal file
@ -0,0 +1,128 @@
|
||||
import { OrganisationGroupType, OrganisationMemberRole } from '@prisma/client';
|
||||
|
||||
export const ORGANISATION_URL_ROOT_REGEX = new RegExp('^/t/[^/]+/?$');
|
||||
export const ORGANISATION_URL_REGEX = new RegExp('^/t/[^/]+');
|
||||
|
||||
export const ORGANISATION_INTERNAL_GROUPS: {
|
||||
organisationRole: OrganisationMemberRole;
|
||||
type: OrganisationGroupType;
|
||||
}[] = [
|
||||
{
|
||||
organisationRole: OrganisationMemberRole.ADMIN,
|
||||
type: OrganisationGroupType.INTERNAL_ORGANISATION,
|
||||
},
|
||||
{
|
||||
organisationRole: OrganisationMemberRole.MANAGER,
|
||||
type: OrganisationGroupType.INTERNAL_ORGANISATION,
|
||||
},
|
||||
{
|
||||
organisationRole: OrganisationMemberRole.MEMBER,
|
||||
type: OrganisationGroupType.INTERNAL_ORGANISATION,
|
||||
},
|
||||
] as const;
|
||||
|
||||
export const ORGANISATION_MEMBER_ROLE_PERMISSIONS_MAP = {
|
||||
/**
|
||||
* Includes permissions to:
|
||||
* - Manage organisation members
|
||||
* - Manage organisation settings, changing name, url, etc.
|
||||
*/
|
||||
DELETE_ORGANISATION: [OrganisationMemberRole.ADMIN],
|
||||
MANAGE_BILLING: [OrganisationMemberRole.ADMIN],
|
||||
DELETE_ORGANISATION_TRANSFER_REQUEST: [OrganisationMemberRole.ADMIN],
|
||||
MANAGE_ORGANISATION: [OrganisationMemberRole.ADMIN, OrganisationMemberRole.MANAGER],
|
||||
} satisfies Record<string, OrganisationMemberRole[]>;
|
||||
|
||||
/**
|
||||
* A hierarchy of organisation member roles to determine which role has higher permission than another.
|
||||
*
|
||||
* Warning: The length of the array is used to determine the priority of the role.
|
||||
* See `getHighestOrganisationRoleInGroup`
|
||||
*/
|
||||
export const ORGANISATION_MEMBER_ROLE_HIERARCHY = {
|
||||
[OrganisationMemberRole.ADMIN]: [
|
||||
OrganisationMemberRole.ADMIN,
|
||||
OrganisationMemberRole.MANAGER,
|
||||
OrganisationMemberRole.MEMBER,
|
||||
],
|
||||
[OrganisationMemberRole.MANAGER]: [OrganisationMemberRole.MANAGER, OrganisationMemberRole.MEMBER],
|
||||
[OrganisationMemberRole.MEMBER]: [OrganisationMemberRole.MEMBER],
|
||||
} satisfies Record<OrganisationMemberRole, OrganisationMemberRole[]>;
|
||||
|
||||
export const LOWEST_ORGANISATION_ROLE = OrganisationMemberRole.MEMBER;
|
||||
|
||||
export const PROTECTED_ORGANISATION_URLS = [
|
||||
'403',
|
||||
'404',
|
||||
'500',
|
||||
'502',
|
||||
'503',
|
||||
'504',
|
||||
'about',
|
||||
'account',
|
||||
'admin',
|
||||
'administrator',
|
||||
'api',
|
||||
'app',
|
||||
'archive',
|
||||
'auth',
|
||||
'backup',
|
||||
'config',
|
||||
'configure',
|
||||
'contact',
|
||||
'contact-us',
|
||||
'copyright',
|
||||
'crime',
|
||||
'criminal',
|
||||
'dashboard',
|
||||
'docs',
|
||||
'documentation',
|
||||
'document',
|
||||
'documents',
|
||||
'error',
|
||||
'exploit',
|
||||
'exploitation',
|
||||
'exploiter',
|
||||
'feedback',
|
||||
'finance',
|
||||
'forgot-password',
|
||||
'fraud',
|
||||
'fraudulent',
|
||||
'hack',
|
||||
'hacker',
|
||||
'harassment',
|
||||
'help',
|
||||
'helpdesk',
|
||||
'illegal',
|
||||
'internal',
|
||||
'legal',
|
||||
'login',
|
||||
'logout',
|
||||
'maintenance',
|
||||
'malware',
|
||||
'newsletter',
|
||||
'policy',
|
||||
'privacy',
|
||||
'profile',
|
||||
'public',
|
||||
'reset-password',
|
||||
'scam',
|
||||
'scammer',
|
||||
'settings',
|
||||
'setup',
|
||||
'sign',
|
||||
'signin',
|
||||
'signout',
|
||||
'signup',
|
||||
'spam',
|
||||
'support',
|
||||
'system',
|
||||
'organisation',
|
||||
'terms',
|
||||
'virus',
|
||||
'webhook',
|
||||
];
|
||||
|
||||
export const isOrganisationUrlProtected = (url: string) => {
|
||||
return PROTECTED_ORGANISATION_URLS.some((protectedUrl) => url.startsWith(`/${protectedUrl}`));
|
||||
};
|
||||
@ -4,39 +4,114 @@ import { RecipientRole } from '@prisma/client';
|
||||
|
||||
export const RECIPIENT_ROLES_DESCRIPTION = {
|
||||
[RecipientRole.APPROVER]: {
|
||||
actionVerb: msg`Approve`,
|
||||
actioned: msg`Approved`,
|
||||
progressiveVerb: msg`Approving`,
|
||||
roleName: msg`Approver`,
|
||||
roleNamePlural: msg`Approvers`,
|
||||
actionVerb: msg({
|
||||
message: `Approve`,
|
||||
context: `Recipient role action verb`,
|
||||
}),
|
||||
actioned: msg({
|
||||
message: `Approved`,
|
||||
context: `Recipient role actioned`,
|
||||
}),
|
||||
progressiveVerb: msg({
|
||||
message: `Approving`,
|
||||
context: `Recipient role progressive verb`,
|
||||
}),
|
||||
roleName: msg({
|
||||
message: `Approver`,
|
||||
context: `Recipient role name`,
|
||||
}),
|
||||
roleNamePlural: msg({
|
||||
message: `Approvers`,
|
||||
context: `Recipient role plural name`,
|
||||
}),
|
||||
},
|
||||
[RecipientRole.CC]: {
|
||||
actionVerb: msg`CC`,
|
||||
actioned: msg`CC'd`,
|
||||
progressiveVerb: msg`CC`,
|
||||
roleName: msg`Cc`,
|
||||
roleNamePlural: msg`Ccers`,
|
||||
actionVerb: msg({
|
||||
message: `CC`,
|
||||
context: `Recipient role action verb`,
|
||||
}),
|
||||
actioned: msg({
|
||||
message: `CC'd`,
|
||||
context: `Recipient role actioned`,
|
||||
}),
|
||||
progressiveVerb: msg({
|
||||
message: `CC`,
|
||||
context: `Recipient role progressive verb`,
|
||||
}),
|
||||
roleName: msg({
|
||||
message: `Cc`,
|
||||
context: `Recipient role name`,
|
||||
}),
|
||||
roleNamePlural: msg({
|
||||
message: `Ccers`,
|
||||
context: `Recipient role plural name`,
|
||||
}),
|
||||
},
|
||||
[RecipientRole.SIGNER]: {
|
||||
actionVerb: msg`Sign`,
|
||||
actioned: msg`Signed`,
|
||||
progressiveVerb: msg`Signing`,
|
||||
roleName: msg`Signer`,
|
||||
roleNamePlural: msg`Signers`,
|
||||
actionVerb: msg({
|
||||
message: `Sign`,
|
||||
context: `Recipient role action verb`,
|
||||
}),
|
||||
actioned: msg({
|
||||
message: `Signed`,
|
||||
context: `Recipient role actioned`,
|
||||
}),
|
||||
progressiveVerb: msg({
|
||||
message: `Signing`,
|
||||
context: `Recipient role progressive verb`,
|
||||
}),
|
||||
roleName: msg({
|
||||
message: `Signer`,
|
||||
context: `Recipient role name`,
|
||||
}),
|
||||
roleNamePlural: msg({
|
||||
message: `Signers`,
|
||||
context: `Recipient role plural name`,
|
||||
}),
|
||||
},
|
||||
[RecipientRole.VIEWER]: {
|
||||
actionVerb: msg`View`,
|
||||
actioned: msg`Viewed`,
|
||||
progressiveVerb: msg`Viewing`,
|
||||
roleName: msg`Viewer`,
|
||||
roleNamePlural: msg`Viewers`,
|
||||
actionVerb: msg({
|
||||
message: `View`,
|
||||
context: `Recipient role action verb`,
|
||||
}),
|
||||
actioned: msg({
|
||||
message: `Viewed`,
|
||||
context: `Recipient role actioned`,
|
||||
}),
|
||||
progressiveVerb: msg({
|
||||
message: `Viewing`,
|
||||
context: `Recipient role progressive verb`,
|
||||
}),
|
||||
roleName: msg({
|
||||
message: `Viewer`,
|
||||
context: `Recipient role name`,
|
||||
}),
|
||||
roleNamePlural: msg({
|
||||
message: `Viewers`,
|
||||
context: `Recipient role plural name`,
|
||||
}),
|
||||
},
|
||||
[RecipientRole.ASSISTANT]: {
|
||||
actionVerb: msg`Assist`,
|
||||
actioned: msg`Assisted`,
|
||||
progressiveVerb: msg`Assisting`,
|
||||
roleName: msg`Assistant`,
|
||||
roleNamePlural: msg`Assistants`,
|
||||
actionVerb: msg({
|
||||
message: `Assist`,
|
||||
context: `Recipient role action verb`,
|
||||
}),
|
||||
actioned: msg({
|
||||
message: `Assisted`,
|
||||
context: `Recipient role actioned`,
|
||||
}),
|
||||
progressiveVerb: msg({
|
||||
message: `Assisting`,
|
||||
context: `Recipient role progressive verb`,
|
||||
}),
|
||||
roleName: msg({
|
||||
message: `Assistant`,
|
||||
context: `Recipient role name`,
|
||||
}),
|
||||
roleNamePlural: msg({
|
||||
message: `Assistants`,
|
||||
context: `Recipient role plural name`,
|
||||
}),
|
||||
},
|
||||
} satisfies Record<keyof typeof RecipientRole, unknown>;
|
||||
|
||||
|
||||
16
packages/lib/constants/teams-translations.ts
Normal file
16
packages/lib/constants/teams-translations.ts
Normal file
@ -0,0 +1,16 @@
|
||||
import type { MessageDescriptor } from '@lingui/core';
|
||||
import { msg } from '@lingui/core/macro';
|
||||
import type { TeamMemberRole } from '@prisma/client';
|
||||
|
||||
export const TEAM_MEMBER_ROLE_MAP: Record<keyof typeof TeamMemberRole, MessageDescriptor> = {
|
||||
ADMIN: msg`Admin`,
|
||||
MANAGER: msg`Manager`,
|
||||
MEMBER: msg`Member`,
|
||||
};
|
||||
|
||||
export const EXTENDED_TEAM_MEMBER_ROLE_MAP: Record<keyof typeof TeamMemberRole, MessageDescriptor> =
|
||||
{
|
||||
ADMIN: msg`Team Admin`,
|
||||
MANAGER: msg`Team Manager`,
|
||||
MEMBER: msg`Team Member`,
|
||||
};
|
||||
@ -1,29 +1,43 @@
|
||||
import type { MessageDescriptor } from '@lingui/core';
|
||||
import { msg } from '@lingui/core/macro';
|
||||
import { TeamMemberRole } from '@prisma/client';
|
||||
import { OrganisationGroupType, TeamMemberRole } from '@prisma/client';
|
||||
|
||||
export const TEAM_URL_ROOT_REGEX = new RegExp('^/t/[^/]+/?$');
|
||||
export const TEAM_URL_REGEX = new RegExp('^/t/[^/]+');
|
||||
|
||||
export const TEAM_MEMBER_ROLE_MAP: Record<keyof typeof TeamMemberRole, MessageDescriptor> = {
|
||||
ADMIN: msg`Admin`,
|
||||
MANAGER: msg`Manager`,
|
||||
MEMBER: msg`Member`,
|
||||
};
|
||||
export const LOWEST_TEAM_ROLE = TeamMemberRole.MEMBER;
|
||||
|
||||
export const ALLOWED_TEAM_GROUP_TYPES: OrganisationGroupType[] = [
|
||||
OrganisationGroupType.CUSTOM,
|
||||
OrganisationGroupType.INTERNAL_ORGANISATION,
|
||||
];
|
||||
|
||||
export const TEAM_INTERNAL_GROUPS: {
|
||||
teamRole: TeamMemberRole;
|
||||
type: OrganisationGroupType;
|
||||
}[] = [
|
||||
{
|
||||
teamRole: TeamMemberRole.ADMIN,
|
||||
type: OrganisationGroupType.INTERNAL_TEAM,
|
||||
},
|
||||
{
|
||||
teamRole: TeamMemberRole.MANAGER,
|
||||
type: OrganisationGroupType.INTERNAL_TEAM,
|
||||
},
|
||||
{
|
||||
teamRole: TeamMemberRole.MEMBER,
|
||||
type: OrganisationGroupType.INTERNAL_TEAM,
|
||||
},
|
||||
] as const;
|
||||
|
||||
export const TEAM_MEMBER_ROLE_PERMISSIONS_MAP = {
|
||||
/**
|
||||
* Includes permissions to:
|
||||
* - Manage team members
|
||||
* - Manage team settings, changing name, url, etc.
|
||||
*/
|
||||
DELETE_TEAM: [TeamMemberRole.ADMIN],
|
||||
MANAGE_TEAM: [TeamMemberRole.ADMIN, TeamMemberRole.MANAGER],
|
||||
MANAGE_BILLING: [TeamMemberRole.ADMIN],
|
||||
DELETE_TEAM_TRANSFER_REQUEST: [TeamMemberRole.ADMIN],
|
||||
} satisfies Record<string, TeamMemberRole[]>;
|
||||
|
||||
/**
|
||||
* A hierarchy of team member roles to determine which role has higher permission than another.
|
||||
*
|
||||
* Warning: The length of the array is used to determine the priority of the role.
|
||||
* See `getHighestTeamRoleInGroup`
|
||||
*/
|
||||
export const TEAM_MEMBER_ROLE_HIERARCHY = {
|
||||
[TeamMemberRole.ADMIN]: [TeamMemberRole.ADMIN, TeamMemberRole.MANAGER, TeamMemberRole.MEMBER],
|
||||
|
||||
@ -3,6 +3,10 @@ import { msg } from '@lingui/core/macro';
|
||||
export const TEMPLATE_RECIPIENT_EMAIL_PLACEHOLDER_REGEX = /recipient\.\d+@documenso\.com/i;
|
||||
export const TEMPLATE_RECIPIENT_NAME_PLACEHOLDER_REGEX = /Recipient \d+/i;
|
||||
|
||||
export const isTemplateRecipientEmailPlaceholder = (email: string) => {
|
||||
return TEMPLATE_RECIPIENT_EMAIL_PLACEHOLDER_REGEX.test(email);
|
||||
};
|
||||
|
||||
export const DIRECT_TEMPLATE_DOCUMENTATION = [
|
||||
{
|
||||
title: msg`Enable Direct Link Signing`,
|
||||
|
||||
Reference in New Issue
Block a user