mirror of
https://github.com/hcengineering/platform.git
synced 2026-09-28 04:25:03 +02:00
feat: added configurable password validation (#7640)
Signed-off-by: Dakshesh Jain <dakshesh.jain14@gmail.com> Signed-off-by: Dakshesh Jain <65905942+dakshesh14@users.noreply.github.com>
This commit is contained in:
@@ -1,14 +1,14 @@
|
||||
{
|
||||
"ACCOUNTS_URL":"/account",
|
||||
"ACCOUNTS_URL": "/account",
|
||||
"COLLABORATOR_URL": "ws://localhost:3078",
|
||||
"UPLOAD_URL":"/files",
|
||||
"UPLOAD_URL": "/files",
|
||||
"TELEGRAM_URL": "http://localhost:8086",
|
||||
"GMAIL_URL": "http://localhost:8088",
|
||||
"CALENDAR_URL": "http://localhost:8095",
|
||||
"REKONI_URL": "/rekoni",
|
||||
"GITHUB_APP": "uberflow-dev",
|
||||
"GITHUB_CLIENTID": "Iv1.43f9cac43bd68617",
|
||||
"GITHUB_URL":"http://localhost:3500",
|
||||
"GITHUB_URL": "http://localhost:3500",
|
||||
"LAST_NAME_FIRST": "true",
|
||||
"PRINT_URL": "http://localhost:4005",
|
||||
"SIGN_URL": "http://localhost:4006",
|
||||
@@ -17,5 +17,6 @@
|
||||
"BRANDING_URL": "/branding.json",
|
||||
"VERSION": null,
|
||||
"MODEL_VERSION": null,
|
||||
"STATS_URL": "http://localhost:4900"
|
||||
}
|
||||
"STATS_URL": "http://localhost:4900",
|
||||
"PASSWORD_STRICTNESS": "none"
|
||||
}
|
||||
|
||||
@@ -158,6 +158,7 @@ export interface Config {
|
||||
AI_URL?:string
|
||||
DISABLE_SIGNUP?: string
|
||||
LINK_PREVIEW_URL?: string
|
||||
PASSWORD_STRICTNESS?: "very_strict" | "strict" | "normal" | "none"
|
||||
// Could be defined for dev environment
|
||||
FRONT_URL?: string
|
||||
PREVIEW_CONFIG?: string
|
||||
@@ -198,6 +199,37 @@ const configs: Record<string, string> = {
|
||||
'dev-worker-local': '/config-worker-local.json',
|
||||
}
|
||||
|
||||
const PASSWORD_REQUIREMENTS : Record<Config['PASSWORD_STRICTNESS'], Record<string, number>> = {
|
||||
very_strict: {
|
||||
MinDigits: 4,
|
||||
MinLength: 32,
|
||||
MinLowerChars: 4,
|
||||
MinSpecialChars: 4,
|
||||
MinUpperChars: 4
|
||||
},
|
||||
strict: {
|
||||
MinDigits: 2,
|
||||
MinLength: 16,
|
||||
MinLowerChars: 2,
|
||||
MinSpecialChars: 2,
|
||||
MinUpperChars: 2
|
||||
},
|
||||
normal: {
|
||||
MinDigits: 1,
|
||||
MinLength: 8,
|
||||
MinLowerChars: 1,
|
||||
MinSpecialChars: 1,
|
||||
MinUpperChars: 1
|
||||
},
|
||||
none: {
|
||||
MinDigits: 0,
|
||||
MinLength: 0,
|
||||
MinLowerChars: 0,
|
||||
MinSpecialChars: 0,
|
||||
MinUpperChars: 0
|
||||
}
|
||||
}
|
||||
|
||||
function configureI18n(): void {
|
||||
//Add localization
|
||||
addStringsLoader(platformId, async (lang: string) => await import(`@hcengineering/platform/lang/${lang}.json`))
|
||||
@@ -306,6 +338,8 @@ export async function configurePlatform() {
|
||||
|
||||
setMetadata(login.metadata.AccountsUrl, config.ACCOUNTS_URL)
|
||||
setMetadata(login.metadata.DisableSignUp, config.DISABLE_SIGNUP === 'true')
|
||||
|
||||
setMetadata(login.metadata.PasswordValidations, PASSWORD_REQUIREMENTS[config.PASSWORD_STRICTNESS ?? 'none'])
|
||||
|
||||
setMetadata(presentation.metadata.FilesURL, config.FILES_URL)
|
||||
setMetadata(presentation.metadata.UploadURL, config.UPLOAD_URL)
|
||||
|
||||
@@ -58,6 +58,11 @@
|
||||
"Skip": "Přeskočit",
|
||||
"SignUpCompleted": "Registrace dokončena",
|
||||
"StartUsingHuly": "Začněte používat Huly",
|
||||
"PasswordMinLength": "{count, plural, =1 {Heslo musí být alespoň # znak dlouhé} other {Heslo musí být alespoň # znaků dlouhé}}",
|
||||
"PasswordMinSpecialChars": "{count, plural, =1 {Heslo musí obsahovat alespoň # speciální znak} other {Heslo musí obsahovat alespoň # speciálních znaků}}",
|
||||
"PasswordMinDigits": "{count, plural, =1 {Heslo musí obsahovat alespoň # číslo} other {Heslo musí obsahovat alespoň # čísel}}",
|
||||
"PasswordMinUpperChars": "{count, plural, =1 {Heslo musí obsahovat alespoň # velké písmeno} other {Heslo musí obsahovat alespoň # velkých písmen}}",
|
||||
"PasswordMinLowerChars": "{count, plural, =1 {Heslo musí obsahovat alespoň # malé písmeno} other {Heslo musí obsahovat alespoň # malých písmen}}",
|
||||
"WorkspaceIsArchived": "Pracovní prostor je archivován kvůli nečinnosti. Kontaktujte nás prosím pro obnovení..."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,6 +58,11 @@
|
||||
"Skip": "Überspringen",
|
||||
"SignUpCompleted": "Registrierung abgeschlossen",
|
||||
"StartUsingHuly": "Starten Sie mit Huly",
|
||||
"PasswordMinLength": "{count, plural, =1 {Das Passwort muss mindestens # Zeichen lang sein} other {Das Passwort muss mindestens # Zeichen lang sein}}",
|
||||
"PasswordMinSpecialChars": "{count, plural, =1 {Das Passwort muss mindestens # Sonderzeichen enthalten} other {Das Passwort muss mindestens # Sonderzeichen enthalten}}",
|
||||
"PasswordMinDigits": "{count, plural, =1 {Das Passwort muss mindestens # Zahl enthalten} other {Das Passwort muss mindestens # Zahlen enthalten}}",
|
||||
"PasswordMinUpperChars": "{count, plural, =1 {Das Passwort muss mindestens # Großbuchstaben enthalten} other {Das Passwort muss mindestens # Großbuchstaben enthalten}}",
|
||||
"PasswordMinLowerChars": "{count, plural, =1 {Das Passwort muss mindestens # Kleinbuchstaben enthalten} other {Das Passwort muss mindestens # Kleinbuchstaben enthalten}}",
|
||||
"WorkspaceArchivedDesc": "Workspace wurde wegen Inaktivität archiviert. Bitte kontaktieren Sie uns zur Wiederherstellung..."
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,6 +58,11 @@
|
||||
"Skip": "Skip",
|
||||
"SignUpCompleted": "Sign up completed",
|
||||
"StartUsingHuly": "Start using Huly",
|
||||
"PasswordMinLength": "{count, plural, =1 {Password must be at least # character long} other {Password must be at least # characters long}}",
|
||||
"PasswordMinSpecialChars": "{count, plural, =1 {Password must contain at least # special character} other {Password must contain at least # special characters}}",
|
||||
"PasswordMinDigits": "{count, plural, =1 {Password must contain at least # number} other {Password must contain at least # numbers}}",
|
||||
"PasswordMinUpperChars": "{count, plural, =1 {Password must contain at least # uppercase letter} other {Password must contain at least # uppercase letters}}",
|
||||
"PasswordMinLowerChars": "{count, plural, =1 {Password must contain at least # lowercase letter} other {Password must contain at least # lowercase letters}}",
|
||||
"WorkspaceArchivedDesc": "Workspace is archived because of being unused, Please contact us to restore..."
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,6 +58,11 @@
|
||||
"Skip": "Saltar",
|
||||
"SignUpCompleted": "Registro completado",
|
||||
"StartUsingHuly": "Comienza a usar Huly",
|
||||
"PasswordMinLength": "{count, plural, =1 {La contraseña debe tener al menos # carácter} other {La contraseña debe tener al menos # caracteres}}",
|
||||
"PasswordMinSpecialChars": "{count, plural, =1 {La contraseña debe contener al menos # carácter especial} other {La contraseña debe contener al menos # caracteres especiales}}",
|
||||
"PasswordMinDigits": "{count, plural, =1 {La contraseña debe contener al menos # número} other {La contraseña debe contener al menos # números}}",
|
||||
"PasswordMinUpperChars": "{count, plural, =1 {La contraseña debe contener al menos # letra mayúscula} other {La contraseña debe contener al menos # letras mayúsculas}}",
|
||||
"PasswordMinLowerChars": "{count, plural, =1 {La contraseña debe contener al menos # letra minúscula} other {La contraseña debe contener al menos # letras minúsculas}}",
|
||||
"WorkspaceArchivedDesc": "El espacio de trabajo está archivado por no estar en uso, por favor contáctenos para restaurarlo..."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,6 +58,11 @@
|
||||
"Skip": "Passer",
|
||||
"SignUpCompleted": "Inscription terminée",
|
||||
"StartUsingHuly": "Commencez à utiliser Huly",
|
||||
"WorkspaceArchivedDesc": "L'espace de travail est archivé en raison de son inactivité, veuillez nous contacter pour le restaurer..."
|
||||
"PasswordMinLength": "{count, plural, =1 {Le mot de passe doit contenir au moins # caractère} other {Le mot de passe doit contenir au moins # caractères}}",
|
||||
"PasswordMinSpecialChars": "{count, plural, =1 {Le mot de passe doit contenir au moins # caractère spécial} other {Le mot de passe doit contenir au moins # caractères spéciaux}}",
|
||||
"PasswordMinDigits": "{count, plural, =1 {Le mot de passe doit contenir au moins # chiffre} other {Le mot de passe doit contenir au moins # chiffres}}",
|
||||
"PasswordMinUpperChars": "{count, plural, =1 {Le mot de passe doit contenir au moins # lettre majuscule} other {Le mot de passe doit contenir au moins # lettres majuscules}}",
|
||||
"PasswordMinLowerChars": "{count, plural, =1 {Le mot de passe doit contenir au moins # lettre minuscule} other {Le mot de passe doit contenir au moins # lettres minuscules}}",
|
||||
"WorkspaceArchivedDesc": "L'espace de travail est archivé en raison de son inactivité, veuillez nous contacter pour le restaurer..."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,6 +58,11 @@
|
||||
"Skip": "Salta",
|
||||
"SignUpCompleted": "Registrazione completata",
|
||||
"StartUsingHuly": "Inizia a usare Huly",
|
||||
"PasswordMinLength": "{count, plural, =1 {La password deve contenere almeno # carattere} other {La password deve contenere almeno # caratteri}}",
|
||||
"PasswordMinSpecialChars": "{count, plural, =1 {La password deve contenere almeno # carattere speciale} other {La password deve contenere almeno # caratteri speciali}}",
|
||||
"PasswordMinDigits": "{count, plural, =1 {La password deve contenere almeno # numero} other {La password deve contenere almeno # numeri}}",
|
||||
"PasswordMinUpperChars": "{count, plural, =1 {La password deve contenere almeno # lettera maiuscola} other {La password deve contenere almeno # lettere maiuscole}}",
|
||||
"PasswordMinLowerChars": "{count, plural, =1 {La password deve contenere almeno # lettera minuscola} other {La password deve contenere almeno # lettere minuscole}}",
|
||||
"WorkspaceArchivedDesc": "Il workspace è stato archiviato perché inutilizzato. Si prega di contattarci per ripristinarlo..."
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,6 +58,11 @@
|
||||
"Skip": "Saltar",
|
||||
"SignUpCompleted": "Registo concluído",
|
||||
"StartUsingHuly": "Começar a usar Huly",
|
||||
"PasswordMinLength": "{count, plural, =1 {A senha deve ter pelo menos # caractere} other {A senha deve ter pelo menos # caracteres}}",
|
||||
"PasswordMinSpecialChars": "{count, plural, =1 {A senha deve conter pelo menos # caractere especial} other {A senha deve conter pelo menos # caracteres especiais}}",
|
||||
"PasswordMinDigits": "{count, plural, =1 {A senha deve conter pelo menos # número} other {A senha deve conter pelo menos # números}}",
|
||||
"PasswordMinUpperChars": "{count, plural, =1 {A senha deve conter pelo menos # letra maiúscula} other {A senha deve conter pelo menos # letras maiúsculas}}",
|
||||
"PasswordMinLowerChars": "{count, plural, =1 {A senha deve conter pelo menos # letra minúscula} other {A senha deve conter pelo menos # letras minúsculas}}",
|
||||
"WorkspaceArchivedDesc": "O espaço de trabalho está arquivado por estar inativo, por favor, entre em contato conosco para restaurá-lo..."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,6 +58,11 @@
|
||||
"Skip": "Пропустить",
|
||||
"SignUpCompleted": "Регистрация завершена",
|
||||
"StartUsingHuly": "Начать использовать Huly",
|
||||
"PasswordMinLength": "{count, plural, =1 {Пароль должен содержать минимум # символ} other {Пароль должен содержать минимум # символов}}",
|
||||
"PasswordMinSpecialChars": "{count, plural, =1 {Пароль должен содержать минимум # специальный символ} other {Пароль должен содержать минимум # специальных символов}}",
|
||||
"PasswordMinDigits": "{count, plural, =1 {Пароль должен содержать минимум # цифру} other {Пароль должен содержать минимум # цифр}}",
|
||||
"PasswordMinUpperChars": "{count, plural, =1 {Пароль должен содержать минимум # заглавную букву} other {Пароль должен содержать минимум # заглавных букв}}",
|
||||
"PasswordMinLowerChars": "{count, plural, =1 {Пароль должен содержать минимум # строчную букву} other {Пароль должен содержать минимум # строчных букв}}",
|
||||
"WorkspaceArchivedDesc": "Рабочее пространство архивировано из-за неиспользования, пожалуйста, свяжитесь с нами для восстановления..."
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,6 +58,11 @@
|
||||
"Skip": "跳过",
|
||||
"SignUpCompleted": "注册完成",
|
||||
"StartUsingHuly": "开始使用 Huly",
|
||||
"PasswordMinLength": "{count, plural, =1 {密码至少需要 # 个字符} other {密码至少需要 # 个字符}}",
|
||||
"PasswordMinSpecialChars": "{count, plural, =1 {密码至少需要 # 个特殊字符} other {密码至少需要 # 个特殊字符}}",
|
||||
"PasswordMinDigits": "{count, plural, =1 {密码至少需要 # 个数字} other {密码至少需要 # 个数字}}",
|
||||
"PasswordMinUpperChars": "{count, plural, =1 {密码至少需要 # 个大写字母} other {密码至少需要 # 个大写字母}}",
|
||||
"PasswordMinLowerChars": "{count, plural, =1 {密码至少需要 # 个小写字母} other {密码至少需要 # 个小写字母}}",
|
||||
"WorkspaceArchivedDesc": "工作区因未使用而归档,请与我们联系以恢复..."
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,25 +22,12 @@
|
||||
import { onMount } from 'svelte'
|
||||
import { BottomAction } from '..'
|
||||
import { makeSequential } from '../mutex'
|
||||
import type { Field } from '../types'
|
||||
import login from '../plugin'
|
||||
import BottomActionComponent from './BottomAction.svelte'
|
||||
import Providers from './Providers.svelte'
|
||||
import Tabs from './Tabs.svelte'
|
||||
|
||||
interface Field {
|
||||
id?: string
|
||||
name: string
|
||||
i18n: IntlString
|
||||
password?: boolean
|
||||
optional?: boolean
|
||||
short?: boolean
|
||||
rules?: {
|
||||
rule: RegExp
|
||||
notMatch: boolean
|
||||
ruleDescr: IntlString
|
||||
}[]
|
||||
}
|
||||
|
||||
interface Action {
|
||||
i18n: IntlString
|
||||
func: () => Promise<void>
|
||||
@@ -85,8 +72,11 @@
|
||||
}
|
||||
if (f.rules !== undefined) {
|
||||
for (const rule of f.rules) {
|
||||
if (rule.rule.test(v) === rule.notMatch) {
|
||||
status = new Status(Severity.INFO, rule.ruleDescr, {})
|
||||
const isValid =
|
||||
typeof rule.rule === 'function' ? rule.rule(v) !== rule.notMatch : rule.rule.test(v) !== rule.notMatch
|
||||
|
||||
if (!isValid) {
|
||||
status = new Status(Severity.INFO, rule.ruleDescr, rule.ruleDescrParams ?? {})
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,11 +18,19 @@
|
||||
import presentation from '@hcengineering/presentation'
|
||||
import { getCurrentLocation, setMetadataLocalStorage } from '@hcengineering/ui'
|
||||
import login from '../plugin'
|
||||
import type { Field } from '../types'
|
||||
import { goTo, restorePassword } from '../utils'
|
||||
import Form from './Form.svelte'
|
||||
import { getPasswordValidationRules } from '../validations'
|
||||
|
||||
const fields = [
|
||||
{ id: 'new-password', name: 'password', i18n: login.string.Password, password: true },
|
||||
const fields: Array<Field> = [
|
||||
{
|
||||
id: 'new-password',
|
||||
name: 'password',
|
||||
i18n: login.string.Password,
|
||||
password: true,
|
||||
rules: getPasswordValidationRules()
|
||||
},
|
||||
{ id: 'new-password', name: 'password2', i18n: login.string.PasswordRepeat, password: true }
|
||||
]
|
||||
|
||||
|
||||
@@ -18,16 +18,24 @@
|
||||
import presentation from '@hcengineering/presentation'
|
||||
import { setMetadataLocalStorage } from '@hcengineering/ui'
|
||||
import login from '../plugin'
|
||||
import { getPasswordValidationRules } from '../validations'
|
||||
import { goTo, signUp } from '../utils'
|
||||
import Form from './Form.svelte'
|
||||
import type { Field } from '../types'
|
||||
|
||||
export let signUpDisabled = false
|
||||
|
||||
const fields = [
|
||||
const fields: Array<Field> = [
|
||||
{ id: 'given-name', name: 'first', i18n: login.string.FirstName, short: true },
|
||||
{ id: 'family-name', name: 'last', i18n: login.string.LastName, short: true },
|
||||
{ id: 'email', name: 'username', i18n: login.string.Email },
|
||||
{ id: 'new-password', name: 'password', i18n: login.string.Password, password: true },
|
||||
{
|
||||
id: 'new-password',
|
||||
name: 'password',
|
||||
i18n: login.string.Password,
|
||||
password: true,
|
||||
rules: getPasswordValidationRules()
|
||||
},
|
||||
{ id: 'new-password', name: 'password2', i18n: login.string.PasswordRepeat, password: true }
|
||||
]
|
||||
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
//
|
||||
// Copyright © 2024 Hardcore Engineering Inc.
|
||||
//
|
||||
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License. You may
|
||||
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
//
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import { type IntlString } from '@hcengineering/platform'
|
||||
|
||||
export interface Field {
|
||||
id?: string
|
||||
name: string
|
||||
i18n: IntlString
|
||||
password?: boolean
|
||||
optional?: boolean
|
||||
short?: boolean
|
||||
rules?: Array<{
|
||||
rule: RegExp | ((value: string) => boolean)
|
||||
notMatch: boolean
|
||||
ruleDescr: IntlString | IntlString<Record<string, any>>
|
||||
ruleDescrParams?: Record<string, any>
|
||||
}>
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
//
|
||||
// Copyright © 2022 Hardcore Engineering Inc.
|
||||
//
|
||||
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License. You may
|
||||
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
//
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import { getMetadata } from '@hcengineering/platform'
|
||||
|
||||
import login from './plugin'
|
||||
import type { Field } from './types'
|
||||
|
||||
/**
|
||||
* Generates password validation rules based on metadata.
|
||||
*
|
||||
* @returns {Field['rules']} An array of password validation rules.
|
||||
*/
|
||||
export function getPasswordValidationRules (): Field['rules'] {
|
||||
const passwordValidations = getMetadata(login.metadata.PasswordValidations)
|
||||
|
||||
const passwordValidationRules: Field['rules'] = [
|
||||
{
|
||||
rule: (value: string) => value.length >= (passwordValidations?.MinLength ?? 0),
|
||||
notMatch: false,
|
||||
ruleDescr: login.string.PasswordMinLength,
|
||||
ruleDescrParams: { count: passwordValidations?.MinLength }
|
||||
},
|
||||
{
|
||||
rule: (value: string) =>
|
||||
(value.match(/[^a-zA-Z0-9]/g)?.length ?? 0) >= (passwordValidations?.MinSpecialChars ?? 0),
|
||||
notMatch: false,
|
||||
ruleDescr: login.string.PasswordMinSpecialChars,
|
||||
ruleDescrParams: { count: passwordValidations?.MinSpecialChars }
|
||||
},
|
||||
{
|
||||
rule: (value: string) => (value.match(/[0-9]/g)?.length ?? 0) >= (passwordValidations?.MinDigits ?? 0),
|
||||
notMatch: false,
|
||||
ruleDescr: login.string.PasswordMinDigits,
|
||||
ruleDescrParams: { count: passwordValidations?.MinDigits }
|
||||
},
|
||||
{
|
||||
rule: (value: string) => (value.match(/[A-Z]/g)?.length ?? 0) >= (passwordValidations?.MinUpperChars ?? 0),
|
||||
notMatch: false,
|
||||
ruleDescr: login.string.PasswordMinUpperChars,
|
||||
ruleDescrParams: { count: passwordValidations?.MinUpperChars }
|
||||
},
|
||||
{
|
||||
rule: (value: string) => (value.match(/[a-z]/g)?.length ?? 0) >= (passwordValidations?.MinLowerChars ?? 0),
|
||||
notMatch: false,
|
||||
ruleDescr: login.string.PasswordMinLowerChars,
|
||||
ruleDescrParams: { count: passwordValidations?.MinLowerChars }
|
||||
}
|
||||
]
|
||||
|
||||
return passwordValidationRules
|
||||
}
|
||||
@@ -72,7 +72,14 @@ export default plugin(loginId, {
|
||||
LoginEndpoint: '' as Metadata<string>,
|
||||
LoginEmail: '' as Metadata<string>,
|
||||
DisableSignUp: '' as Metadata<boolean>,
|
||||
TransactorOverride: '' as Metadata<string>
|
||||
TransactorOverride: '' as Metadata<string>,
|
||||
PasswordValidations: '' as Metadata<{
|
||||
MinLength: number
|
||||
MinSpecialChars: number
|
||||
MinDigits: number
|
||||
MinUpperChars: number
|
||||
MinLowerChars: number
|
||||
}>
|
||||
},
|
||||
component: {
|
||||
LoginApp: '' as AnyComponent,
|
||||
@@ -86,6 +93,11 @@ export default plugin(loginId, {
|
||||
EmailMask: '' as IntlString,
|
||||
NoLimit: '' as IntlString,
|
||||
InviteLimit: '' as IntlString,
|
||||
PasswordMinLength: '' as IntlString<{ count: number }>,
|
||||
PasswordMinSpecialChars: '' as IntlString<{ count: number }>,
|
||||
PasswordMinDigits: '' as IntlString<{ count: number }>,
|
||||
PasswordMinUpperChars: '' as IntlString<{ count: number }>,
|
||||
PasswordMinLowerChars: '' as IntlString<{ count: number }>,
|
||||
WorkspaceArchived: '' as IntlString,
|
||||
WorkspaceArchivedDesc: '' as IntlString
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user