mirror of
https://github.com/logto-io/logto.git
synced 2024-12-16 20:26:19 -05:00
feat: default user role (#5872)
* feat: default user role * chore: add tests and changeset * refactor: show warning for deprecated env * chore: fix tests
This commit is contained in:
parent
13bfdbd638
commit
76fd33b7ed
89 changed files with 467 additions and 238 deletions
8
.changeset/spicy-drinks-camp.md
Normal file
8
.changeset/spicy-drinks-camp.md
Normal file
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
"@logto/console": minor
|
||||
"@logto/phrases": minor
|
||||
"@logto/schemas": minor
|
||||
"@logto/core": minor
|
||||
---
|
||||
|
||||
support default roles for users
|
|
@ -47,7 +47,7 @@
|
|||
},
|
||||
"prettier": "@silverhand/eslint-config/.prettierrc",
|
||||
"dependencies": {
|
||||
"@silverhand/essentials": "^2.9.0",
|
||||
"@silverhand/essentials": "^2.9.1",
|
||||
"applicationinsights": "^2.9.5"
|
||||
},
|
||||
"peerDependencies": {
|
||||
|
|
|
@ -49,7 +49,7 @@
|
|||
"@logto/phrases-experience": "workspace:^1.6.1",
|
||||
"@logto/schemas": "workspace:1.16.0",
|
||||
"@logto/shared": "workspace:^3.1.1",
|
||||
"@silverhand/essentials": "^2.9.0",
|
||||
"@silverhand/essentials": "^2.9.1",
|
||||
"@silverhand/slonik": "31.0.0-beta.2",
|
||||
"chalk": "^5.0.0",
|
||||
"decamelize": "^6.0.0",
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import type { AlterationScript } from '@logto/schemas/lib/types/alteration.js';
|
||||
import { conditionalString } from '@silverhand/essentials';
|
||||
import type { DatabasePool } from '@silverhand/slonik';
|
||||
import type { CommonQueryMethods, DatabasePool } from '@silverhand/slonik';
|
||||
import chalk from 'chalk';
|
||||
import type { CommandModule } from 'yargs';
|
||||
|
||||
|
@ -39,7 +39,7 @@ export const getLatestAlterationTimestamp = async () => {
|
|||
};
|
||||
|
||||
export const getAvailableAlterations = async (
|
||||
pool: DatabasePool,
|
||||
pool: CommonQueryMethods,
|
||||
compareMode: 'gt' | 'lte' = 'gt'
|
||||
) => {
|
||||
const databaseTimestamp = await getCurrentDatabaseAlterationTimestamp(pool);
|
||||
|
|
|
@ -355,7 +355,7 @@ const traverseNode = async (
|
|||
await traverseObject(baseline, targetObject, 2);
|
||||
|
||||
await (isRoot
|
||||
? fs.appendFile(targetFilePath, '} satisfies LocalePhrase;\n\n')
|
||||
? fs.appendFile(targetFilePath, '} satisfies DeepPartial<LocalePhrase>;\n\n')
|
||||
: fs.appendFile(targetFilePath, '};\n\n'));
|
||||
await fs.appendFile(targetFilePath, `export default Object.freeze(${identifier});\n`);
|
||||
};
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
"author": "Silverhand Inc. <contact@silverhand.io>",
|
||||
"dependencies": {
|
||||
"@logto/connector-kit": "workspace:^3.0.0",
|
||||
"@silverhand/essentials": "^2.9.0",
|
||||
"@silverhand/essentials": "^2.9.1",
|
||||
"dayjs": "^1.10.5",
|
||||
"got": "^14.0.0",
|
||||
"iconv-lite": "^0.6.3",
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
"description": "Alipay implementation.",
|
||||
"dependencies": {
|
||||
"@logto/connector-kit": "workspace:^3.0.0",
|
||||
"@silverhand/essentials": "^2.9.0",
|
||||
"@silverhand/essentials": "^2.9.1",
|
||||
"dayjs": "^1.10.5",
|
||||
"got": "^14.0.0",
|
||||
"iconv-lite": "^0.6.3",
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
"description": "Aliyun DM connector implementation.",
|
||||
"dependencies": {
|
||||
"@logto/connector-kit": "workspace:^3.0.0",
|
||||
"@silverhand/essentials": "^2.9.0",
|
||||
"@silverhand/essentials": "^2.9.1",
|
||||
"got": "^14.0.0",
|
||||
"snakecase-keys": "^8.0.0",
|
||||
"zod": "^3.22.4"
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
"description": "Aliyun SMS connector implementation.",
|
||||
"dependencies": {
|
||||
"@logto/connector-kit": "workspace:^3.0.0",
|
||||
"@silverhand/essentials": "^2.9.0",
|
||||
"@silverhand/essentials": "^2.9.1",
|
||||
"got": "^14.0.0",
|
||||
"snakecase-keys": "^8.0.0",
|
||||
"zod": "^3.22.4"
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
"dependencies": {
|
||||
"@logto/connector-kit": "workspace:^3.0.0",
|
||||
"@logto/shared": "workspace:^3.1.0",
|
||||
"@silverhand/essentials": "^2.9.0",
|
||||
"@silverhand/essentials": "^2.9.1",
|
||||
"got": "^14.0.0",
|
||||
"jose": "^5.0.0",
|
||||
"snakecase-keys": "^8.0.0",
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
"@aws-sdk/client-sesv2": "^3.556.0",
|
||||
"@aws-sdk/types": "^3.535.0",
|
||||
"@logto/connector-kit": "workspace:^3.0.0",
|
||||
"@silverhand/essentials": "^2.9.0",
|
||||
"@silverhand/essentials": "^2.9.1",
|
||||
"got": "^14.0.0",
|
||||
"snakecase-keys": "^8.0.0",
|
||||
"zod": "^3.22.4"
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
"dependencies": {
|
||||
"@azure/msal-node": "^2.0.0",
|
||||
"@logto/connector-kit": "workspace:^3.0.0",
|
||||
"@silverhand/essentials": "^2.9.0",
|
||||
"@silverhand/essentials": "^2.9.1",
|
||||
"got": "^14.0.0",
|
||||
"snakecase-keys": "^8.0.0",
|
||||
"zod": "^3.22.4"
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
"author": "ZR3SYSTEMS. <https://github.com/FlurryNight>",
|
||||
"dependencies": {
|
||||
"@logto/connector-kit": "workspace:^3.0.0",
|
||||
"@silverhand/essentials": "^2.9.0",
|
||||
"@silverhand/essentials": "^2.9.1",
|
||||
"got": "^14.0.0",
|
||||
"snakecase-keys": "^8.0.0",
|
||||
"zod": "^3.22.4"
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
"author": "Silverhand Inc. <contact@silverhand.io>",
|
||||
"dependencies": {
|
||||
"@logto/connector-kit": "workspace:^3.0.0",
|
||||
"@silverhand/essentials": "^2.9.0",
|
||||
"@silverhand/essentials": "^2.9.1",
|
||||
"got": "^14.0.0",
|
||||
"snakecase-keys": "^8.0.0",
|
||||
"zod": "^3.22.4"
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
"author": "Silverhand Inc. <contact@silverhand.io>",
|
||||
"dependencies": {
|
||||
"@logto/connector-kit": "workspace:^3.0.0",
|
||||
"@silverhand/essentials": "^2.9.0",
|
||||
"@silverhand/essentials": "^2.9.1",
|
||||
"got": "^14.0.0",
|
||||
"snakecase-keys": "^8.0.0",
|
||||
"zod": "^3.22.4"
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
"author": "Silverhand Inc. <contact@silverhand.io>",
|
||||
"dependencies": {
|
||||
"@logto/connector-kit": "workspace:^3.0.0",
|
||||
"@silverhand/essentials": "^2.9.0",
|
||||
"@silverhand/essentials": "^2.9.1",
|
||||
"ky": "^1.2.3",
|
||||
"query-string": "^9.0.0",
|
||||
"snakecase-keys": "^8.0.0",
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
"author": "Silverhand Inc. <contact@silverhand.io>",
|
||||
"dependencies": {
|
||||
"@logto/connector-kit": "workspace:^3.0.0",
|
||||
"@silverhand/essentials": "^2.9.0",
|
||||
"@silverhand/essentials": "^2.9.1",
|
||||
"got": "^14.0.0",
|
||||
"snakecase-keys": "^8.0.0",
|
||||
"zod": "^3.22.4"
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
"dependencies": {
|
||||
"@logto/connector-kit": "workspace:^3.0.0",
|
||||
"@logto/connector-oauth": "workspace:^1.3.0",
|
||||
"@silverhand/essentials": "^2.9.0",
|
||||
"@silverhand/essentials": "^2.9.1",
|
||||
"ky": "^1.2.3",
|
||||
"zod": "^3.22.4"
|
||||
},
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
"author": "Kyungyoon Kim. <ruddbs5302@gmail.com>",
|
||||
"dependencies": {
|
||||
"@logto/connector-kit": "workspace:^3.0.0",
|
||||
"@silverhand/essentials": "^2.9.0",
|
||||
"@silverhand/essentials": "^2.9.1",
|
||||
"got": "^14.0.0",
|
||||
"snakecase-keys": "^8.0.0",
|
||||
"zod": "^3.22.4"
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
"author": "Silverhand Inc. <contact@silverhand.io>",
|
||||
"dependencies": {
|
||||
"@logto/connector-kit": "workspace:^3.0.0",
|
||||
"@silverhand/essentials": "^2.9.0",
|
||||
"@silverhand/essentials": "^2.9.1",
|
||||
"got": "^14.0.0",
|
||||
"snakecase-keys": "^8.0.0",
|
||||
"zod": "^3.22.4"
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
"author": "Silverhand Inc. <contact@silverhand.io>",
|
||||
"dependencies": {
|
||||
"@logto/connector-kit": "workspace:^3.0.0",
|
||||
"@silverhand/essentials": "^2.9.0",
|
||||
"@silverhand/essentials": "^2.9.1",
|
||||
"got": "^14.0.0",
|
||||
"snakecase-keys": "^8.0.0",
|
||||
"zod": "^3.22.4"
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
"author": "Silverhand Inc. <contact@silverhand.io>",
|
||||
"dependencies": {
|
||||
"@logto/connector-kit": "workspace:^3.0.0",
|
||||
"@silverhand/essentials": "^2.9.0",
|
||||
"@silverhand/essentials": "^2.9.1",
|
||||
"got": "^14.0.0",
|
||||
"snakecase-keys": "^8.0.0",
|
||||
"zod": "^3.22.4"
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
"author": "Silverhand Inc. <contact@silverhand.io>",
|
||||
"dependencies": {
|
||||
"@logto/connector-kit": "workspace:^3.0.0",
|
||||
"@silverhand/essentials": "^2.9.0",
|
||||
"@silverhand/essentials": "^2.9.1",
|
||||
"got": "^14.0.0",
|
||||
"snakecase-keys": "^8.0.0",
|
||||
"zod": "^3.22.4"
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
"author": "Silverhand Inc. <contact@silverhand.io>",
|
||||
"dependencies": {
|
||||
"@logto/connector-kit": "workspace:^3.0.0",
|
||||
"@silverhand/essentials": "^2.9.0",
|
||||
"@silverhand/essentials": "^2.9.1",
|
||||
"got": "^14.0.0",
|
||||
"snakecase-keys": "^8.0.0",
|
||||
"zod": "^3.22.4"
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
"author": "Silverhand Inc. <contact@silverhand.io>",
|
||||
"dependencies": {
|
||||
"@logto/connector-kit": "workspace:^3.0.0",
|
||||
"@silverhand/essentials": "^2.9.0",
|
||||
"@silverhand/essentials": "^2.9.1",
|
||||
"got": "^14.0.0",
|
||||
"snakecase-keys": "^8.0.0",
|
||||
"zod": "^3.22.4"
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
"author": "Silverhand Inc. <contact@silverhand.io>",
|
||||
"dependencies": {
|
||||
"@logto/connector-kit": "workspace:^3.0.0",
|
||||
"@silverhand/essentials": "^2.9.0",
|
||||
"@silverhand/essentials": "^2.9.1",
|
||||
"got": "^14.0.0",
|
||||
"snakecase-keys": "^8.0.0",
|
||||
"zod": "^3.22.4"
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
"author": "Silverhand Inc. <contact@silverhand.io>",
|
||||
"dependencies": {
|
||||
"@logto/connector-kit": "workspace:^3.0.0",
|
||||
"@silverhand/essentials": "^2.9.0",
|
||||
"@silverhand/essentials": "^2.9.1",
|
||||
"got": "^14.0.0",
|
||||
"snakecase-keys": "^8.0.0",
|
||||
"zod": "^3.22.4"
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
"author": "Kyungyoon Kim. <ruddbs5302@gmail.com>",
|
||||
"dependencies": {
|
||||
"@logto/connector-kit": "workspace:^3.0.0",
|
||||
"@silverhand/essentials": "^2.9.0",
|
||||
"@silverhand/essentials": "^2.9.1",
|
||||
"got": "^14.0.0",
|
||||
"snakecase-keys": "^8.0.0",
|
||||
"zod": "^3.22.4"
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
"dependencies": {
|
||||
"@logto/connector-kit": "workspace:^3.0.0",
|
||||
"@logto/shared": "workspace:^3.1.1",
|
||||
"@silverhand/essentials": "^2.9.0",
|
||||
"@silverhand/essentials": "^2.9.1",
|
||||
"jose": "^5.0.0",
|
||||
"ky": "^1.2.3",
|
||||
"query-string": "^9.0.0",
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
"@logto/connector-kit": "workspace:^3.0.0",
|
||||
"@logto/connector-oauth": "workspace:^1.3.0",
|
||||
"@logto/shared": "workspace:^3.1.1",
|
||||
"@silverhand/essentials": "^2.9.0",
|
||||
"@silverhand/essentials": "^2.9.1",
|
||||
"jose": "^5.0.0",
|
||||
"ky": "^1.2.3",
|
||||
"nanoid": "^5.0.1",
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
"author": "Silverhand Inc. <contact@silverhand.io>",
|
||||
"dependencies": {
|
||||
"@logto/connector-kit": "workspace:^3.0.0",
|
||||
"@silverhand/essentials": "^2.9.0",
|
||||
"@silverhand/essentials": "^2.9.1",
|
||||
"fast-xml-parser": "^4.3.6",
|
||||
"got": "^14.0.0",
|
||||
"samlify": "2.8.11",
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
"author": "Silverhand Inc. <contact@silverhand.io>",
|
||||
"dependencies": {
|
||||
"@logto/connector-kit": "workspace:^3.0.0",
|
||||
"@silverhand/essentials": "^2.9.0",
|
||||
"@silverhand/essentials": "^2.9.1",
|
||||
"got": "^14.0.0",
|
||||
"snakecase-keys": "^8.0.0",
|
||||
"zod": "^3.22.4"
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
"author": "Danil Tankov <danil.tankoff@yandex.ru>",
|
||||
"dependencies": {
|
||||
"@logto/connector-kit": "workspace:^3.0.0",
|
||||
"@silverhand/essentials": "^2.9.0",
|
||||
"@silverhand/essentials": "^2.9.1",
|
||||
"got": "^14.0.0",
|
||||
"snakecase-keys": "^8.0.0",
|
||||
"zod": "^3.22.4"
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
"author": "Silverhand Inc. <contact@silverhand.io>",
|
||||
"dependencies": {
|
||||
"@logto/connector-kit": "workspace:^3.0.0",
|
||||
"@silverhand/essentials": "^2.9.0",
|
||||
"@silverhand/essentials": "^2.9.1",
|
||||
"got": "^14.0.0",
|
||||
"nodemailer": "^6.9.9",
|
||||
"snakecase-keys": "^8.0.0",
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
"author": "StringKe",
|
||||
"dependencies": {
|
||||
"@logto/connector-kit": "workspace:^3.0.0",
|
||||
"@silverhand/essentials": "^2.9.0",
|
||||
"@silverhand/essentials": "^2.9.1",
|
||||
"got": "^14.0.0",
|
||||
"snakecase-keys": "^8.0.0",
|
||||
"zod": "^3.22.4"
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
"author": "Silverhand Inc. <contact@silverhand.io>",
|
||||
"dependencies": {
|
||||
"@logto/connector-kit": "workspace:^3.0.0",
|
||||
"@silverhand/essentials": "^2.9.0",
|
||||
"@silverhand/essentials": "^2.9.1",
|
||||
"got": "^14.0.0",
|
||||
"snakecase-keys": "^8.0.0",
|
||||
"zod": "^3.22.4"
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
"author": "Silverhand Inc. <contact@silverhand.io>",
|
||||
"dependencies": {
|
||||
"@logto/connector-kit": "workspace:^3.0.0",
|
||||
"@silverhand/essentials": "^2.9.0",
|
||||
"@silverhand/essentials": "^2.9.1",
|
||||
"got": "^14.0.0",
|
||||
"snakecase-keys": "^8.0.0",
|
||||
"zod": "^3.22.4"
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
"author": "Silverhand Inc. <contact@silverhand.io>",
|
||||
"dependencies": {
|
||||
"@logto/connector-kit": "workspace:^3.0.0",
|
||||
"@silverhand/essentials": "^2.9.0",
|
||||
"@silverhand/essentials": "^2.9.1",
|
||||
"got": "^14.0.0",
|
||||
"snakecase-keys": "^8.0.0",
|
||||
"zod": "^3.22.4"
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
"author": "Dove<dove@feegr.cc> fork from Wechat Web connector",
|
||||
"dependencies": {
|
||||
"@logto/connector-kit": "workspace:^3.0.0",
|
||||
"@silverhand/essentials": "^2.9.0",
|
||||
"@silverhand/essentials": "^2.9.1",
|
||||
"got": "^14.0.0",
|
||||
"snakecase-keys": "^8.0.0",
|
||||
"zod": "^3.22.4"
|
||||
|
|
|
@ -46,7 +46,7 @@
|
|||
"@parcel/transformer-svg-react": "2.9.3",
|
||||
"@silverhand/eslint-config": "6.0.1",
|
||||
"@silverhand/eslint-config-react": "6.0.2",
|
||||
"@silverhand/essentials": "^2.9.0",
|
||||
"@silverhand/essentials": "^2.9.1",
|
||||
"@silverhand/ts-config": "6.0.0",
|
||||
"@silverhand/ts-config-react": "6.0.0",
|
||||
"@swc/core": "^1.3.52",
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import type { Role } from '@logto/schemas';
|
||||
import { RoleType, type Role } from '@logto/schemas';
|
||||
import { useForm } from 'react-hook-form';
|
||||
import { toast } from 'react-hot-toast';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
@ -8,6 +8,7 @@ import DetailsForm from '@/components/DetailsForm';
|
|||
import FormCard from '@/components/FormCard';
|
||||
import UnsavedChangesAlertModal from '@/components/UnsavedChangesAlertModal';
|
||||
import FormField from '@/ds-components/FormField';
|
||||
import Switch from '@/ds-components/Switch';
|
||||
import TextInput from '@/ds-components/TextInput';
|
||||
import useApi from '@/hooks/use-api';
|
||||
import { trySubmitSafe } from '@/utils/form';
|
||||
|
@ -66,6 +67,14 @@ function RoleSettings() {
|
|||
error={Boolean(errors.description)}
|
||||
/>
|
||||
</FormField>
|
||||
{role.type === RoleType.User && (
|
||||
<FormField title="role_details.field_is_default">
|
||||
<Switch
|
||||
label={t('role_details.field_is_default_description')}
|
||||
{...register('isDefault')}
|
||||
/>
|
||||
</FormField>
|
||||
)}
|
||||
</FormCard>
|
||||
</DetailsForm>
|
||||
<UnsavedChangesAlertModal hasUnsavedChanges={!isDeleting && isDirty} />
|
||||
|
|
|
@ -18,8 +18,8 @@ mockEsm('#src/libraries/logto-config.js', () => ({
|
|||
createLogtoConfigLibrary: () => ({ getOidcConfigs: () => ({}) }),
|
||||
}));
|
||||
|
||||
mockEsm('#src/env-set/check-alteration-state.js', () => ({
|
||||
checkAlterationState: () => true,
|
||||
mockEsm('#src/env-set/preconditions.js', () => ({
|
||||
checkPreconditions: () => true,
|
||||
}));
|
||||
|
||||
// eslint-disable-next-line unicorn/consistent-function-scoping
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
"@logto/phrases-experience": "workspace:^1.6.1",
|
||||
"@logto/schemas": "workspace:^1.16.0",
|
||||
"@logto/shared": "workspace:^3.1.1",
|
||||
"@silverhand/essentials": "^2.9.0",
|
||||
"@silverhand/essentials": "^2.9.1",
|
||||
"@silverhand/slonik": "31.0.0-beta.2",
|
||||
"@simplewebauthn/server": "^10.0.0",
|
||||
"@withtyped/client": "^0.8.7",
|
||||
|
|
|
@ -122,6 +122,7 @@ export const mockAdminApplicationRole: Role = {
|
|||
name: 'admin',
|
||||
description: 'admin application',
|
||||
type: RoleType.MachineToMachine,
|
||||
isDefault: false,
|
||||
};
|
||||
|
||||
export const mockAdminUserRole: Role = {
|
||||
|
@ -130,6 +131,7 @@ export const mockAdminUserRole: Role = {
|
|||
name: 'admin',
|
||||
description: 'admin',
|
||||
type: RoleType.User,
|
||||
isDefault: false,
|
||||
};
|
||||
|
||||
export const mockAdminUserRole2: Role = {
|
||||
|
@ -138,6 +140,7 @@ export const mockAdminUserRole2: Role = {
|
|||
name: 'admin2',
|
||||
description: 'admin2',
|
||||
type: RoleType.User,
|
||||
isDefault: false,
|
||||
};
|
||||
|
||||
export const mockAdminUserRole3: Role = {
|
||||
|
@ -146,6 +149,7 @@ export const mockAdminUserRole3: Role = {
|
|||
name: 'admin3',
|
||||
description: 'admin3',
|
||||
type: RoleType.MachineToMachine,
|
||||
isDefault: false,
|
||||
};
|
||||
|
||||
export const mockAdminConsoleData: AdminConsoleData = {
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
import { getAvailableAlterations } from '@logto/cli/lib/commands/database/alteration/index.js';
|
||||
import { ConsoleLog } from '@logto/shared';
|
||||
import type { DatabasePool } from '@silverhand/slonik';
|
||||
import chalk from 'chalk';
|
||||
|
||||
const consoleLog = new ConsoleLog(chalk.magenta('db-alt'));
|
||||
|
||||
export const checkAlterationState = async (pool: DatabasePool) => {
|
||||
const alterations = await getAvailableAlterations(pool);
|
||||
|
||||
if (alterations.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
consoleLog.error(
|
||||
`Found undeployed database alterations, you must deploy them first by ${chalk.green(
|
||||
'npm run alteration deploy'
|
||||
)} command.\n\n` +
|
||||
` See ${chalk.blue(
|
||||
'https://docs.logto.io/docs/tutorials/using-cli/database-alteration'
|
||||
)} for reference.\n`
|
||||
);
|
||||
|
||||
throw new Error(`Undeployed database alterations found.`);
|
||||
};
|
69
packages/core/src/env-set/preconditions.ts
Normal file
69
packages/core/src/env-set/preconditions.ts
Normal file
|
@ -0,0 +1,69 @@
|
|||
import { getAvailableAlterations } from '@logto/cli/lib/commands/database/alteration/index.js';
|
||||
import { ServiceLogs, Systems } from '@logto/schemas';
|
||||
import { ConsoleLog, isKeyInObject } from '@logto/shared';
|
||||
import { conditionalString } from '@silverhand/essentials';
|
||||
import { sql, type CommonQueryMethods, type DatabasePool } from '@silverhand/slonik';
|
||||
import chalk from 'chalk';
|
||||
|
||||
import { EnvSet } from './index.js';
|
||||
|
||||
const consoleLog = new ConsoleLog(chalk.magenta('pre'));
|
||||
|
||||
export const checkPreconditions = async (pool: DatabasePool) => {
|
||||
checkDeprecations();
|
||||
await Promise.all([checkAlterationState(pool), checkRowLevelSecurity(pool)]);
|
||||
};
|
||||
|
||||
const checkRowLevelSecurity = async (client: CommonQueryMethods) => {
|
||||
const { rows } = await client.query(sql`
|
||||
select tablename
|
||||
from pg_catalog.pg_tables
|
||||
where schemaname = current_schema()
|
||||
and rowsecurity=false
|
||||
`);
|
||||
|
||||
const rlsDisabled = rows.filter(
|
||||
({ tablename }) => tablename !== Systems.table && tablename !== ServiceLogs.table
|
||||
);
|
||||
|
||||
if (rlsDisabled.length > 0) {
|
||||
throw new Error(
|
||||
'Row-level security has to be enforced on EVERY business table when starting Logto.\n' +
|
||||
`Found following table(s) without RLS: ${rlsDisabled
|
||||
.map((row) => conditionalString(isKeyInObject(row, 'tablename') && String(row.tablename)))
|
||||
.join(', ')}\n\n` +
|
||||
'Did you forget to run `npm cli db alteration deploy`?'
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const checkAlterationState = async (pool: CommonQueryMethods) => {
|
||||
const alterations = await getAvailableAlterations(pool);
|
||||
|
||||
if (alterations.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
consoleLog.error(
|
||||
`Found undeployed database alterations, you must deploy them first by ${chalk.green(
|
||||
'npm run alteration deploy'
|
||||
)} command.\n\n` +
|
||||
` See ${chalk.blue(
|
||||
'https://docs.logto.io/docs/tutorials/using-cli/database-alteration'
|
||||
)} for reference.\n`
|
||||
);
|
||||
|
||||
throw new Error(`Undeployed database alterations found.`);
|
||||
};
|
||||
|
||||
const checkDeprecations = () => {
|
||||
if (EnvSet.values.userDefaultRoleNames.length > 0) {
|
||||
consoleLog.warn(
|
||||
`The environment variable ${chalk.green(
|
||||
'USER_DEFAULT_ROLE_NAMES'
|
||||
)} is deprecated and will be removed in the next major version. Please use the built-in user default role configuration (${chalk.green(
|
||||
'Roles.isDefault'
|
||||
)}) instead.\n`
|
||||
);
|
||||
}
|
||||
};
|
|
@ -1,8 +1,7 @@
|
|||
import type { User, CreateUser, Scope, BindMfa, MfaVerification } from '@logto/schemas';
|
||||
import { MfaFactor, Users, UsersPasswordEncryptionMethod } from '@logto/schemas';
|
||||
import { MfaFactor, RoleType, Users, UsersPasswordEncryptionMethod } from '@logto/schemas';
|
||||
import { generateStandardShortId, generateStandardId } from '@logto/shared';
|
||||
import type { Nullable } from '@silverhand/essentials';
|
||||
import { deduplicate } from '@silverhand/essentials';
|
||||
import { deduplicateByKey, type Nullable } from '@silverhand/essentials';
|
||||
import { argon2Verify, bcryptVerify, md5, sha1, sha256 } from 'hash-wasm';
|
||||
import pRetry from 'p-retry';
|
||||
|
||||
|
@ -75,7 +74,7 @@ export type UserLibrary = ReturnType<typeof createUserLibrary>;
|
|||
export const createUserLibrary = (queries: Queries) => {
|
||||
const {
|
||||
pool,
|
||||
roles: { findRolesByRoleNames, findRoleByRoleName, findRolesByRoleIds },
|
||||
roles: { findDefaultRoles, findRolesByRoleNames, findRoleByRoleName, findRolesByRoleIds },
|
||||
users: {
|
||||
hasUser,
|
||||
hasUserWithEmail,
|
||||
|
@ -107,10 +106,13 @@ export const createUserLibrary = (queries: Queries) => {
|
|||
);
|
||||
|
||||
const insertUser = async (data: OmitAutoSetFields<CreateUser>, additionalRoleNames: string[]) => {
|
||||
const roleNames = deduplicate([...EnvSet.values.userDefaultRoleNames, ...additionalRoleNames]);
|
||||
const roles = await findRolesByRoleNames(roleNames);
|
||||
const roleNames = [...EnvSet.values.userDefaultRoleNames, ...additionalRoleNames];
|
||||
const [parameterRoles, defaultRoles] = await Promise.all([
|
||||
findRolesByRoleNames(roleNames),
|
||||
findDefaultRoles(RoleType.User),
|
||||
]);
|
||||
|
||||
assertThat(roles.length === roleNames.length, 'role.default_role_missing');
|
||||
assertThat(parameterRoles.length === roleNames.length, 'role.default_role_missing');
|
||||
|
||||
return pool.transaction(async (connection) => {
|
||||
const insertUserQuery = buildInsertIntoWithPool(connection)(Users, {
|
||||
|
@ -118,6 +120,7 @@ export const createUserLibrary = (queries: Queries) => {
|
|||
});
|
||||
|
||||
const user = await insertUserQuery(data);
|
||||
const roles = deduplicateByKey([...parameterRoles, ...defaultRoles], 'id');
|
||||
|
||||
if (roles.length > 0) {
|
||||
const { insertUsersRoles } = createUsersRolesQueries(connection);
|
||||
|
|
|
@ -6,11 +6,11 @@ import Koa from 'koa';
|
|||
|
||||
import initApp from './app/init.js';
|
||||
import { redisCache } from './caches/index.js';
|
||||
import { checkAlterationState } from './env-set/check-alteration-state.js';
|
||||
import { EnvSet } from './env-set/index.js';
|
||||
import { checkPreconditions } from './env-set/preconditions.js';
|
||||
import initI18n from './i18n/init.js';
|
||||
import SystemContext from './tenants/SystemContext.js';
|
||||
import { checkRowLevelSecurity, tenantPool } from './tenants/index.js';
|
||||
import { tenantPool } from './tenants/index.js';
|
||||
import { loadConnectorFactories } from './utils/connectors/index.js';
|
||||
|
||||
const consoleLog = new ConsoleLog(chalk.magenta('index'));
|
||||
|
@ -29,8 +29,7 @@ try {
|
|||
initI18n(),
|
||||
redisCache.connect(),
|
||||
loadConnectorFactories(),
|
||||
checkRowLevelSecurity(sharedAdminPool),
|
||||
checkAlterationState(sharedAdminPool),
|
||||
checkPreconditions(sharedAdminPool),
|
||||
SystemContext.shared.loadProviderConfigs(sharedAdminPool),
|
||||
]);
|
||||
|
||||
|
|
|
@ -135,7 +135,7 @@ describe('roles query', () => {
|
|||
const keys = excludeAutoSetFields(Roles.fieldKeys);
|
||||
|
||||
const expectSql = `
|
||||
insert into "roles" ("id", "name", "description", "type")
|
||||
insert into "roles" ("id", "name", "description", "type", "is_default")
|
||||
values (${keys.map((_, index) => `$${index + 1}`).join(', ')})
|
||||
returning *
|
||||
`;
|
||||
|
|
|
@ -95,6 +95,16 @@ export const createRolesQueries = (pool: CommonQueryMethods) => {
|
|||
`)
|
||||
: [];
|
||||
|
||||
const findDefaultRoles = async (forType: RoleType.User) =>
|
||||
pool.any<Role>(
|
||||
sql`
|
||||
select ${sql.join(Object.values(fields), sql`, `)}
|
||||
from ${table}
|
||||
where ${fields.isDefault} is true
|
||||
and ${fields.type}=${forType}
|
||||
`
|
||||
);
|
||||
|
||||
const findRolesByRoleNames = async (roleNames: string[]) =>
|
||||
roleNames.length > 0
|
||||
? pool.any<Role>(sql`
|
||||
|
@ -147,6 +157,7 @@ export const createRolesQueries = (pool: CommonQueryMethods) => {
|
|||
countRoles,
|
||||
findRoles,
|
||||
findRolesByRoleIds,
|
||||
findDefaultRoles,
|
||||
findRolesByRoleNames,
|
||||
findRoleByRoleName,
|
||||
insertRoles,
|
||||
|
|
|
@ -51,6 +51,7 @@ const mockedQueries = {
|
|||
name: 'admin',
|
||||
description: 'none',
|
||||
type: RoleType.User,
|
||||
isDefault: false,
|
||||
},
|
||||
]
|
||||
),
|
||||
|
|
|
@ -39,6 +39,7 @@ const mockedQueries = {
|
|||
name: 'admin',
|
||||
description: 'none',
|
||||
type: RoleType.User,
|
||||
isDefault: false,
|
||||
},
|
||||
]
|
||||
),
|
||||
|
|
|
@ -18,6 +18,7 @@ const roles = {
|
|||
findRoleByRoleName: jest.fn(async (): Promise<Role | null> => null),
|
||||
insertRole: jest.fn(async (data) => ({
|
||||
type: mockAdminUserRole.type,
|
||||
isDefault: false,
|
||||
...data,
|
||||
id: mockAdminUserRole.id,
|
||||
tenantId: 'fake_tenant',
|
||||
|
|
|
@ -201,7 +201,7 @@ export default function roleRoutes<T extends ManagementApiRouter>(
|
|||
router.patch(
|
||||
'/roles/:id',
|
||||
koaGuard({
|
||||
body: Roles.createGuard.pick({ name: true, description: true }).partial(),
|
||||
body: Roles.createGuard.pick({ name: true, description: true, isDefault: true }).partial(),
|
||||
params: object({ id: string().min(1) }),
|
||||
response: Roles.guard,
|
||||
status: [200, 404, 422],
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
import { ServiceLogs, Systems } from '@logto/schemas';
|
||||
import { Tenants } from '@logto/schemas/models';
|
||||
import { isKeyInObject } from '@logto/shared';
|
||||
import { conditional, conditionalString } from '@silverhand/essentials';
|
||||
import type { CommonQueryMethods } from '@silverhand/slonik';
|
||||
import { conditional } from '@silverhand/essentials';
|
||||
import { parseDsn, sql, stringifyDsn } from '@silverhand/slonik';
|
||||
import { z } from 'zod';
|
||||
|
||||
|
@ -46,26 +43,3 @@ export const getTenantDatabaseDsn = async (tenantId: string) => {
|
|||
password: conditional(typeof password === 'string' && password),
|
||||
});
|
||||
};
|
||||
|
||||
export const checkRowLevelSecurity = async (client: CommonQueryMethods) => {
|
||||
const { rows } = await client.query(sql`
|
||||
select tablename
|
||||
from pg_catalog.pg_tables
|
||||
where schemaname = current_schema()
|
||||
and rowsecurity=false
|
||||
`);
|
||||
|
||||
const rlsDisabled = rows.filter(
|
||||
({ tablename }) => tablename !== Systems.table && tablename !== ServiceLogs.table
|
||||
);
|
||||
|
||||
if (rlsDisabled.length > 0) {
|
||||
throw new Error(
|
||||
'Row-level security has to be enforced on EVERY business table when starting Logto.\n' +
|
||||
`Found following table(s) without RLS: ${rlsDisabled
|
||||
.map((row) => conditionalString(isKeyInObject(row, 'tablename') && String(row.tablename)))
|
||||
.join(', ')}\n\n` +
|
||||
'Did you forget to run `npm cli db alteration deploy`?'
|
||||
);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -110,7 +110,7 @@ const App = () => {
|
|||
config={{
|
||||
endpoint: window.location.origin,
|
||||
appId: demoAppApplicationId,
|
||||
prompt: Prompt.Login,
|
||||
prompt: [Prompt.Login, Prompt.Consent],
|
||||
scopes: [UserScope.Organizations, UserScope.OrganizationRoles],
|
||||
}}
|
||||
>
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
"@react-spring/web": "^9.6.1",
|
||||
"@silverhand/eslint-config": "6.0.1",
|
||||
"@silverhand/eslint-config-react": "6.0.2",
|
||||
"@silverhand/essentials": "^2.9.0",
|
||||
"@silverhand/essentials": "^2.9.1",
|
||||
"@silverhand/ts-config": "6.0.0",
|
||||
"@silverhand/ts-config-react": "6.0.0",
|
||||
"@simplewebauthn/browser": "^10.0.0",
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
"@logto/schemas": "workspace:^1.16.0",
|
||||
"@logto/shared": "workspace:^3.1.1",
|
||||
"@silverhand/eslint-config": "6.0.1",
|
||||
"@silverhand/essentials": "^2.9.0",
|
||||
"@silverhand/essentials": "^2.9.1",
|
||||
"@silverhand/ts-config": "6.0.0",
|
||||
"@types/jest": "^29.4.0",
|
||||
"@types/node": "^20.9.5",
|
||||
|
|
|
@ -16,11 +16,13 @@ export const createRole = async ({
|
|||
name,
|
||||
description,
|
||||
type,
|
||||
isDefault,
|
||||
scopeIds,
|
||||
}: {
|
||||
name?: string;
|
||||
description?: string;
|
||||
type?: RoleType;
|
||||
isDefault?: boolean;
|
||||
scopeIds?: string[];
|
||||
}) =>
|
||||
authedAdminApi
|
||||
|
@ -28,6 +30,7 @@ export const createRole = async ({
|
|||
json: {
|
||||
name: name ?? generateRoleName(),
|
||||
description: description ?? generateRoleName(),
|
||||
isDefault,
|
||||
type: type ?? RoleType.User,
|
||||
scopeIds,
|
||||
},
|
||||
|
|
|
@ -148,6 +148,10 @@ export default class MockClient {
|
|||
return this.logto.getAccessToken(resource, organizationId);
|
||||
}
|
||||
|
||||
public async getAccessTokenClaims(resource?: string) {
|
||||
return this.logto.getAccessTokenClaims(resource);
|
||||
}
|
||||
|
||||
public async getRefreshToken(): Promise<Nullable<string>> {
|
||||
return this.logto.getRefreshToken();
|
||||
}
|
||||
|
|
107
packages/integration-tests/src/tests/api/role.is-default.test.ts
Normal file
107
packages/integration-tests/src/tests/api/role.is-default.test.ts
Normal file
|
@ -0,0 +1,107 @@
|
|||
import {
|
||||
InteractionEvent,
|
||||
SignInIdentifier,
|
||||
type Resource,
|
||||
type Role,
|
||||
type Scope,
|
||||
} from '@logto/schemas';
|
||||
import { noop } from '@silverhand/essentials';
|
||||
|
||||
import { createUser, deleteUser, getUserRoles } from '#src/api/admin-user.js';
|
||||
import { putInteraction, updateSignInExperience } from '#src/api/index.js';
|
||||
import { createResource, deleteResource } from '#src/api/resource.js';
|
||||
import { assignScopesToRole, createRole, deleteRole } from '#src/api/role.js';
|
||||
import { createScope } from '#src/api/scope.js';
|
||||
import { initClient, processSession } from '#src/helpers/client.js';
|
||||
import { enableAllPasswordSignInMethods } from '#src/helpers/sign-in-experience.js';
|
||||
import { generatePassword, generateUsername } from '#src/utils.js';
|
||||
|
||||
class TestContext {
|
||||
resource?: Resource;
|
||||
scopes: Scope[] = [];
|
||||
roles: Role[] = [];
|
||||
}
|
||||
|
||||
describe('default roles', () => {
|
||||
const context = new TestContext();
|
||||
|
||||
beforeAll(async () => {
|
||||
await enableAllPasswordSignInMethods({
|
||||
identifiers: [SignInIdentifier.Username],
|
||||
password: true,
|
||||
verify: false,
|
||||
});
|
||||
await updateSignInExperience({ passwordPolicy: { length: { max: 256 } } });
|
||||
|
||||
// Set up a resource with two scopes and two default roles, each with one of the scopes
|
||||
const resource = await createResource();
|
||||
const scopes = await Promise.all([createScope(resource.id), createScope(resource.id)]);
|
||||
const roles = await Promise.all([
|
||||
createRole({ isDefault: true }),
|
||||
createRole({ isDefault: true }),
|
||||
]);
|
||||
await Promise.all([
|
||||
assignScopesToRole([scopes[0].id], roles[0].id),
|
||||
assignScopesToRole([scopes[1].id], roles[1].id),
|
||||
]);
|
||||
|
||||
/* eslint-disable @silverhand/fp/no-mutation */
|
||||
context.resource = resource;
|
||||
context.scopes = scopes;
|
||||
context.roles = roles;
|
||||
/* eslint-enable @silverhand/fp/no-mutation */
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await Promise.all(
|
||||
[
|
||||
...context.roles.map(async (role) => deleteRole(role.id)),
|
||||
deleteResource(context.resource!.id),
|
||||
].map(async (promise) => promise.catch(noop))
|
||||
);
|
||||
});
|
||||
|
||||
it('should automatically assign default roles to new users created via Management API', async () => {
|
||||
// Create a new user
|
||||
const user = await createUser();
|
||||
|
||||
// Check that the user has the default roles
|
||||
const userRoles = await getUserRoles(user.id);
|
||||
expect(userRoles.map((role) => role.id)).toEqual(
|
||||
expect.arrayContaining(context.roles.map((role) => role.id))
|
||||
);
|
||||
|
||||
await deleteUser(user.id);
|
||||
});
|
||||
|
||||
it('should automatically assign default roles to new users via sign-in experience', async () => {
|
||||
const username = generateUsername();
|
||||
const password = generatePassword();
|
||||
|
||||
// Process the sign-in flow
|
||||
const client = await initClient({
|
||||
resources: [context.resource!.indicator],
|
||||
scopes: context.scopes.map((scope) => scope.name),
|
||||
});
|
||||
await client.successSend(putInteraction, {
|
||||
event: InteractionEvent.Register,
|
||||
profile: { username, password },
|
||||
});
|
||||
const { redirectTo } = await client.submitInteraction();
|
||||
const userId = await processSession(client, redirectTo);
|
||||
|
||||
// Check claims and roles
|
||||
const claims = await client.getAccessTokenClaims(context.resource!.indicator);
|
||||
expect(claims.scope?.split(' ')).toEqual(
|
||||
expect.arrayContaining(context.scopes.map((scope) => scope.name))
|
||||
);
|
||||
|
||||
const roles = await getUserRoles(userId);
|
||||
expect(roles.map((role) => role.id)).toEqual(
|
||||
expect.arrayContaining(context.roles.map((role) => role.id))
|
||||
);
|
||||
|
||||
// Clean up
|
||||
await deleteUser(userId);
|
||||
});
|
||||
});
|
|
@ -35,7 +35,7 @@
|
|||
"dependencies": {
|
||||
"@logto/core-kit": "workspace:^2.4.0",
|
||||
"@logto/language-kit": "workspace:^1.1.0",
|
||||
"@silverhand/essentials": "^2.9.0"
|
||||
"@silverhand/essentials": "^2.9.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"zod": "^3.22.4"
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@logto/language-kit": "workspace:^1.1.0",
|
||||
"@silverhand/essentials": "^2.9.0"
|
||||
"@silverhand/essentials": "^2.9.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"zod": "^3.22.4"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import type { LanguageTag } from '@logto/language-kit';
|
||||
import { languages, fallback } from '@logto/language-kit';
|
||||
import type { NormalizeKeyPaths } from '@silverhand/essentials';
|
||||
import type { DeepPartial, NormalizeKeyPaths } from '@silverhand/essentials';
|
||||
import { z } from 'zod';
|
||||
|
||||
import de from './locales/de/index.js';
|
||||
|
@ -22,6 +22,7 @@ import type { LocalePhrase } from './types.js';
|
|||
|
||||
export type { LocalePhrase } from './types.js';
|
||||
|
||||
export type DefaultLocale = 'en';
|
||||
export type I18nKey = NormalizeKeyPaths<typeof en.translation>;
|
||||
|
||||
export const builtInLanguages = [
|
||||
|
@ -63,7 +64,12 @@ export const getDefaultLanguageTag = (languages: string): LanguageTag =>
|
|||
export const isBuiltInLanguageTag = (language: string): language is BuiltInLanguageTag =>
|
||||
builtInLanguageTagGuard.safeParse(language).success;
|
||||
|
||||
export type Resource = Record<BuiltInLanguageTag, LocalePhrase>;
|
||||
export type Resource = Record<
|
||||
Exclude<BuiltInLanguageTag, DefaultLocale>,
|
||||
DeepPartial<LocalePhrase>
|
||||
> & {
|
||||
[key in DefaultLocale]: LocalePhrase;
|
||||
};
|
||||
|
||||
const resource: Resource = {
|
||||
de,
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import { type DeepPartial } from '@silverhand/essentials';
|
||||
|
||||
import type { LocalePhrase } from '../../types.js';
|
||||
|
||||
import errors from './errors/index.js';
|
||||
|
@ -6,6 +8,6 @@ import translation from './translation/index.js';
|
|||
const de = {
|
||||
translation,
|
||||
errors,
|
||||
} satisfies LocalePhrase;
|
||||
} satisfies DeepPartial<LocalePhrase>;
|
||||
|
||||
export default Object.freeze(de);
|
||||
|
|
|
@ -13,6 +13,9 @@ const role_details = {
|
|||
'Roles are a grouping of permissions that can be assigned to users. They also provide a way to aggregate permissions defined for different APIs, making it more efficient to add, remove, or adjust permissions compared to assigning them individually to users.',
|
||||
field_name: 'Name',
|
||||
field_description: 'Description',
|
||||
field_is_default: 'Default role',
|
||||
field_is_default_description:
|
||||
'Set this role as a default role for new users. Multiple default roles can be set. This will also affect the default roles for users created via Management API.',
|
||||
type_m2m_role_tag: 'Machine-to-machine app role',
|
||||
type_user_role_tag: 'User role',
|
||||
permission: {
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import { type DeepPartial } from '@silverhand/essentials';
|
||||
|
||||
import type { LocalePhrase } from '../../types.js';
|
||||
|
||||
import errors from './errors/index.js';
|
||||
|
@ -6,6 +8,6 @@ import translation from './translation/index.js';
|
|||
const es = {
|
||||
translation,
|
||||
errors,
|
||||
} satisfies LocalePhrase;
|
||||
} satisfies DeepPartial<LocalePhrase>;
|
||||
|
||||
export default Object.freeze(es);
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import { type DeepPartial } from '@silverhand/essentials';
|
||||
|
||||
import type { LocalePhrase } from '../../types.js';
|
||||
|
||||
import errors from './errors/index.js';
|
||||
|
@ -6,6 +8,6 @@ import translation from './translation/index.js';
|
|||
const fr = {
|
||||
translation,
|
||||
errors,
|
||||
} satisfies LocalePhrase;
|
||||
} satisfies DeepPartial<LocalePhrase>;
|
||||
|
||||
export default Object.freeze(fr);
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import { type DeepPartial } from '@silverhand/essentials';
|
||||
|
||||
import type { LocalePhrase } from '../../types.js';
|
||||
|
||||
import errors from './errors/index.js';
|
||||
|
@ -6,6 +8,6 @@ import translation from './translation/index.js';
|
|||
const it = {
|
||||
translation,
|
||||
errors,
|
||||
} satisfies LocalePhrase;
|
||||
} satisfies DeepPartial<LocalePhrase>;
|
||||
|
||||
export default Object.freeze(it);
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import { type DeepPartial } from '@silverhand/essentials';
|
||||
|
||||
import type { LocalePhrase } from '../../types.js';
|
||||
|
||||
import errors from './errors/index.js';
|
||||
|
@ -6,6 +8,6 @@ import translation from './translation/index.js';
|
|||
const ja = {
|
||||
translation,
|
||||
errors,
|
||||
} satisfies LocalePhrase;
|
||||
} satisfies DeepPartial<LocalePhrase>;
|
||||
|
||||
export default Object.freeze(ja);
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import { type DeepPartial } from '@silverhand/essentials';
|
||||
|
||||
import type { LocalePhrase } from '../../types.js';
|
||||
|
||||
import errors from './errors/index.js';
|
||||
|
@ -6,6 +8,6 @@ import translation from './translation/index.js';
|
|||
const ko = {
|
||||
translation,
|
||||
errors,
|
||||
} satisfies LocalePhrase;
|
||||
} satisfies DeepPartial<LocalePhrase>;
|
||||
|
||||
export default Object.freeze(ko);
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import { type DeepPartial } from '@silverhand/essentials';
|
||||
|
||||
import type { LocalePhrase } from '../../types.js';
|
||||
|
||||
import errors from './errors/index.js';
|
||||
|
@ -6,6 +8,6 @@ import translation from './translation/index.js';
|
|||
const pl_pl = {
|
||||
translation,
|
||||
errors,
|
||||
} satisfies LocalePhrase;
|
||||
} satisfies DeepPartial<LocalePhrase>;
|
||||
|
||||
export default Object.freeze(pl_pl);
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import { type DeepPartial } from '@silverhand/essentials';
|
||||
|
||||
import type { LocalePhrase } from '../../types.js';
|
||||
|
||||
import errors from './errors/index.js';
|
||||
|
@ -6,6 +8,6 @@ import translation from './translation/index.js';
|
|||
const pt_br = {
|
||||
translation,
|
||||
errors,
|
||||
} satisfies LocalePhrase;
|
||||
} satisfies DeepPartial<LocalePhrase>;
|
||||
|
||||
export default Object.freeze(pt_br);
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import { type DeepPartial } from '@silverhand/essentials';
|
||||
|
||||
import type { LocalePhrase } from '../../types.js';
|
||||
|
||||
import errors from './errors/index.js';
|
||||
|
@ -6,6 +8,6 @@ import translation from './translation/index.js';
|
|||
const pt_pt = {
|
||||
translation,
|
||||
errors,
|
||||
} satisfies LocalePhrase;
|
||||
} satisfies DeepPartial<LocalePhrase>;
|
||||
|
||||
export default Object.freeze(pt_pt);
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import { type DeepPartial } from '@silverhand/essentials';
|
||||
|
||||
import type { LocalePhrase } from '../../types.js';
|
||||
|
||||
import errors from './errors/index.js';
|
||||
|
@ -6,6 +8,6 @@ import translation from './translation/index.js';
|
|||
const ru = {
|
||||
translation,
|
||||
errors,
|
||||
} satisfies LocalePhrase;
|
||||
} satisfies DeepPartial<LocalePhrase>;
|
||||
|
||||
export default Object.freeze(ru);
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import { type DeepPartial } from '@silverhand/essentials';
|
||||
|
||||
import type { LocalePhrase } from '../../types.js';
|
||||
|
||||
import errors from './errors/index.js';
|
||||
|
@ -6,6 +8,6 @@ import translation from './translation/index.js';
|
|||
const tr_tr = {
|
||||
translation,
|
||||
errors,
|
||||
} satisfies LocalePhrase;
|
||||
} satisfies DeepPartial<LocalePhrase>;
|
||||
|
||||
export default Object.freeze(tr_tr);
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import { type DeepPartial } from '@silverhand/essentials';
|
||||
|
||||
import type { LocalePhrase } from '../../types.js';
|
||||
|
||||
import errors from './errors/index.js';
|
||||
|
@ -6,6 +8,6 @@ import translation from './translation/index.js';
|
|||
const zh_cn = {
|
||||
translation,
|
||||
errors,
|
||||
} satisfies LocalePhrase;
|
||||
} satisfies DeepPartial<LocalePhrase>;
|
||||
|
||||
export default Object.freeze(zh_cn);
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import { type DeepPartial } from '@silverhand/essentials';
|
||||
|
||||
import type { LocalePhrase } from '../../types.js';
|
||||
|
||||
import errors from './errors/index.js';
|
||||
|
@ -6,6 +8,6 @@ import translation from './translation/index.js';
|
|||
const zh_hk = {
|
||||
translation,
|
||||
errors,
|
||||
} satisfies LocalePhrase;
|
||||
} satisfies DeepPartial<LocalePhrase>;
|
||||
|
||||
export default Object.freeze(zh_hk);
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import { type DeepPartial } from '@silverhand/essentials';
|
||||
|
||||
import type { LocalePhrase } from '../../types.js';
|
||||
|
||||
import errors from './errors/index.js';
|
||||
|
@ -6,6 +8,6 @@ import translation from './translation/index.js';
|
|||
const zh_tw = {
|
||||
translation,
|
||||
errors,
|
||||
} satisfies LocalePhrase;
|
||||
} satisfies DeepPartial<LocalePhrase>;
|
||||
|
||||
export default Object.freeze(zh_tw);
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
import { sql } from '@silverhand/slonik';
|
||||
|
||||
import type { AlterationScript } from '../lib/types/alteration.js';
|
||||
|
||||
const alteration: AlterationScript = {
|
||||
up: async (pool) => {
|
||||
await pool.query(sql`
|
||||
alter table roles add column is_default boolean not null default false;
|
||||
`);
|
||||
},
|
||||
down: async (pool) => {
|
||||
await pool.query(sql`
|
||||
alter table roles drop column is_default;
|
||||
`);
|
||||
},
|
||||
};
|
||||
|
||||
export default alteration;
|
|
@ -40,7 +40,7 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@silverhand/eslint-config": "6.0.1",
|
||||
"@silverhand/essentials": "^2.9.0",
|
||||
"@silverhand/essentials": "^2.9.1",
|
||||
"@silverhand/slonik": "31.0.0-beta.2",
|
||||
"@silverhand/ts-config": "6.0.0",
|
||||
"@types/inquirer": "^9.0.0",
|
||||
|
|
|
@ -85,4 +85,5 @@ export const createTenantApplicationRole = (): Readonly<Role> => ({
|
|||
description:
|
||||
'The role for M2M applications that represent a user tenant and send requests to Logto Cloud.',
|
||||
type: RoleType.MachineToMachine,
|
||||
isDefault: false,
|
||||
});
|
||||
|
|
|
@ -36,6 +36,7 @@ export const getMapiProxyRole = (tenantId: string): Readonly<Role> =>
|
|||
name: `machine:mapi:${tenantId}`,
|
||||
description: `Machine-to-machine role for accessing Management API of tenant '${tenantId}'.`,
|
||||
type: RoleType.MachineToMachine,
|
||||
isDefault: false,
|
||||
});
|
||||
|
||||
/**
|
||||
|
|
|
@ -9,6 +9,8 @@ create table roles (
|
|||
name varchar(128) not null,
|
||||
description varchar(128) not null,
|
||||
type role_type not null default 'User',
|
||||
/** If the role is the default role for a new user. Should be ignored for `MachineToMachine` roles. */
|
||||
is_default boolean not null default false,
|
||||
primary key (id),
|
||||
constraint roles__name
|
||||
unique (tenant_id, name)
|
||||
|
|
|
@ -59,7 +59,7 @@
|
|||
},
|
||||
"prettier": "@silverhand/eslint-config/.prettierrc",
|
||||
"dependencies": {
|
||||
"@silverhand/essentials": "^2.9.0",
|
||||
"@silverhand/essentials": "^2.9.1",
|
||||
"chalk": "^5.0.0",
|
||||
"find-up": "^7.0.0",
|
||||
"libphonenumber-js": "^1.9.49",
|
||||
|
|
1
packages/shared/src/node/env/GlobalValues.ts
vendored
1
packages/shared/src/node/env/GlobalValues.ts
vendored
|
@ -94,6 +94,7 @@ export default class GlobalValues {
|
|||
// eslint-disable-next-line unicorn/consistent-function-scoping
|
||||
public readonly databaseUrl = tryThat(() => assertEnv('DB_URL'), throwErrorWithDsnMessage);
|
||||
public readonly developmentTenantId = getEnv('DEVELOPMENT_TENANT_ID');
|
||||
/** @deprecated Use the built-in user default role configuration (`Roles.isDefault`) instead. */
|
||||
public readonly userDefaultRoleNames = getEnvAsStringArray('USER_DEFAULT_ROLE_NAMES');
|
||||
public readonly developmentUserId = getEnv('DEVELOPMENT_USER_ID');
|
||||
public readonly trustProxyHeader = yes(getEnv('TRUST_PROXY_HEADER'));
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@logto/language-kit": "workspace:^1.1.0",
|
||||
"@silverhand/essentials": "^2.9.0",
|
||||
"@silverhand/essentials": "^2.9.1",
|
||||
"@withtyped/client": "^0.8.7",
|
||||
"@withtyped/server": "^0.13.6"
|
||||
},
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
"dependencies": {
|
||||
"@logto/language-kit": "workspace:^1.1.0",
|
||||
"@logto/shared": "workspace:^3.1.0",
|
||||
"@silverhand/essentials": "^2.9.0",
|
||||
"@silverhand/essentials": "^2.9.1",
|
||||
"color": "^4.2.3"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
|
|
208
pnpm-lock.yaml
208
pnpm-lock.yaml
|
@ -43,8 +43,8 @@ importers:
|
|||
packages/app-insights:
|
||||
dependencies:
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.9.0
|
||||
version: 2.9.0
|
||||
specifier: ^2.9.1
|
||||
version: 2.9.1
|
||||
applicationinsights:
|
||||
specifier: ^2.9.5
|
||||
version: 2.9.5
|
||||
|
@ -104,8 +104,8 @@ importers:
|
|||
specifier: workspace:^3.1.1
|
||||
version: link:../shared
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.9.0
|
||||
version: 2.9.0
|
||||
specifier: ^2.9.1
|
||||
version: 2.9.1
|
||||
'@silverhand/slonik':
|
||||
specifier: 31.0.0-beta.2
|
||||
version: 31.0.0-beta.2
|
||||
|
@ -216,8 +216,8 @@ importers:
|
|||
specifier: workspace:^3.0.0
|
||||
version: link:../../toolkit/connector-kit
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.9.0
|
||||
version: 2.9.0
|
||||
specifier: ^2.9.1
|
||||
version: 2.9.1
|
||||
dayjs:
|
||||
specifier: ^1.10.5
|
||||
version: 1.11.6
|
||||
|
@ -298,8 +298,8 @@ importers:
|
|||
specifier: workspace:^3.0.0
|
||||
version: link:../../toolkit/connector-kit
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.9.0
|
||||
version: 2.9.0
|
||||
specifier: ^2.9.1
|
||||
version: 2.9.1
|
||||
dayjs:
|
||||
specifier: ^1.10.5
|
||||
version: 1.11.6
|
||||
|
@ -380,8 +380,8 @@ importers:
|
|||
specifier: workspace:^3.0.0
|
||||
version: link:../../toolkit/connector-kit
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.9.0
|
||||
version: 2.9.0
|
||||
specifier: ^2.9.1
|
||||
version: 2.9.1
|
||||
got:
|
||||
specifier: ^14.0.0
|
||||
version: 14.0.0
|
||||
|
@ -453,8 +453,8 @@ importers:
|
|||
specifier: workspace:^3.0.0
|
||||
version: link:../../toolkit/connector-kit
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.9.0
|
||||
version: 2.9.0
|
||||
specifier: ^2.9.1
|
||||
version: 2.9.1
|
||||
got:
|
||||
specifier: ^14.0.0
|
||||
version: 14.0.0
|
||||
|
@ -529,8 +529,8 @@ importers:
|
|||
specifier: workspace:^3.1.0
|
||||
version: link:../../shared
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.9.0
|
||||
version: 2.9.0
|
||||
specifier: ^2.9.1
|
||||
version: 2.9.1
|
||||
got:
|
||||
specifier: ^14.0.0
|
||||
version: 14.0.0
|
||||
|
@ -611,8 +611,8 @@ importers:
|
|||
specifier: workspace:^3.0.0
|
||||
version: link:../../toolkit/connector-kit
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.9.0
|
||||
version: 2.9.0
|
||||
specifier: ^2.9.1
|
||||
version: 2.9.1
|
||||
got:
|
||||
specifier: ^14.0.0
|
||||
version: 14.0.0
|
||||
|
@ -687,8 +687,8 @@ importers:
|
|||
specifier: workspace:^3.0.0
|
||||
version: link:../../toolkit/connector-kit
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.9.0
|
||||
version: 2.9.0
|
||||
specifier: ^2.9.1
|
||||
version: 2.9.1
|
||||
got:
|
||||
specifier: ^14.0.0
|
||||
version: 14.0.0
|
||||
|
@ -760,8 +760,8 @@ importers:
|
|||
specifier: workspace:^3.0.0
|
||||
version: link:../../toolkit/connector-kit
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.9.0
|
||||
version: 2.9.0
|
||||
specifier: ^2.9.1
|
||||
version: 2.9.1
|
||||
got:
|
||||
specifier: ^14.0.0
|
||||
version: 14.0.0
|
||||
|
@ -833,8 +833,8 @@ importers:
|
|||
specifier: workspace:^3.0.0
|
||||
version: link:../../toolkit/connector-kit
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.9.0
|
||||
version: 2.9.0
|
||||
specifier: ^2.9.1
|
||||
version: 2.9.1
|
||||
got:
|
||||
specifier: ^14.0.0
|
||||
version: 14.0.0
|
||||
|
@ -906,8 +906,8 @@ importers:
|
|||
specifier: workspace:^3.0.0
|
||||
version: link:../../toolkit/connector-kit
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.9.0
|
||||
version: 2.9.0
|
||||
specifier: ^2.9.1
|
||||
version: 2.9.1
|
||||
got:
|
||||
specifier: ^14.0.0
|
||||
version: 14.0.0
|
||||
|
@ -979,8 +979,8 @@ importers:
|
|||
specifier: workspace:^3.0.0
|
||||
version: link:../../toolkit/connector-kit
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.9.0
|
||||
version: 2.9.0
|
||||
specifier: ^2.9.1
|
||||
version: 2.9.1
|
||||
ky:
|
||||
specifier: ^1.2.3
|
||||
version: 1.2.3
|
||||
|
@ -1055,8 +1055,8 @@ importers:
|
|||
specifier: workspace:^3.0.0
|
||||
version: link:../../toolkit/connector-kit
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.9.0
|
||||
version: 2.9.0
|
||||
specifier: ^2.9.1
|
||||
version: 2.9.1
|
||||
got:
|
||||
specifier: ^14.0.0
|
||||
version: 14.0.0
|
||||
|
@ -1131,8 +1131,8 @@ importers:
|
|||
specifier: workspace:^1.3.0
|
||||
version: link:../connector-oauth2
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.9.0
|
||||
version: 2.9.0
|
||||
specifier: ^2.9.1
|
||||
version: 2.9.1
|
||||
ky:
|
||||
specifier: ^1.2.3
|
||||
version: 1.2.3
|
||||
|
@ -1201,8 +1201,8 @@ importers:
|
|||
specifier: workspace:^3.0.0
|
||||
version: link:../../toolkit/connector-kit
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.9.0
|
||||
version: 2.9.0
|
||||
specifier: ^2.9.1
|
||||
version: 2.9.1
|
||||
got:
|
||||
specifier: ^14.0.0
|
||||
version: 14.0.0
|
||||
|
@ -1274,8 +1274,8 @@ importers:
|
|||
specifier: workspace:^3.0.0
|
||||
version: link:../../toolkit/connector-kit
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.9.0
|
||||
version: 2.9.0
|
||||
specifier: ^2.9.1
|
||||
version: 2.9.1
|
||||
got:
|
||||
specifier: ^14.0.0
|
||||
version: 14.0.0
|
||||
|
@ -1350,8 +1350,8 @@ importers:
|
|||
specifier: workspace:^3.0.0
|
||||
version: link:../../toolkit/connector-kit
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.9.0
|
||||
version: 2.9.0
|
||||
specifier: ^2.9.1
|
||||
version: 2.9.1
|
||||
got:
|
||||
specifier: ^14.0.0
|
||||
version: 14.0.0
|
||||
|
@ -1423,8 +1423,8 @@ importers:
|
|||
specifier: workspace:^3.0.0
|
||||
version: link:../../toolkit/connector-kit
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.9.0
|
||||
version: 2.9.0
|
||||
specifier: ^2.9.1
|
||||
version: 2.9.1
|
||||
got:
|
||||
specifier: ^14.0.0
|
||||
version: 14.0.0
|
||||
|
@ -1496,8 +1496,8 @@ importers:
|
|||
specifier: workspace:^3.0.0
|
||||
version: link:../../toolkit/connector-kit
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.9.0
|
||||
version: 2.9.0
|
||||
specifier: ^2.9.1
|
||||
version: 2.9.1
|
||||
got:
|
||||
specifier: ^14.0.0
|
||||
version: 14.0.0
|
||||
|
@ -1569,8 +1569,8 @@ importers:
|
|||
specifier: workspace:^3.0.0
|
||||
version: link:../../toolkit/connector-kit
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.9.0
|
||||
version: 2.9.0
|
||||
specifier: ^2.9.1
|
||||
version: 2.9.1
|
||||
got:
|
||||
specifier: ^14.0.0
|
||||
version: 14.0.0
|
||||
|
@ -1642,8 +1642,8 @@ importers:
|
|||
specifier: workspace:^3.0.0
|
||||
version: link:../../toolkit/connector-kit
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.9.0
|
||||
version: 2.9.0
|
||||
specifier: ^2.9.1
|
||||
version: 2.9.1
|
||||
got:
|
||||
specifier: ^14.0.0
|
||||
version: 14.0.0
|
||||
|
@ -1715,8 +1715,8 @@ importers:
|
|||
specifier: workspace:^3.0.0
|
||||
version: link:../../toolkit/connector-kit
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.9.0
|
||||
version: 2.9.0
|
||||
specifier: ^2.9.1
|
||||
version: 2.9.1
|
||||
got:
|
||||
specifier: ^14.0.0
|
||||
version: 14.0.0
|
||||
|
@ -1788,8 +1788,8 @@ importers:
|
|||
specifier: workspace:^3.0.0
|
||||
version: link:../../toolkit/connector-kit
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.9.0
|
||||
version: 2.9.0
|
||||
specifier: ^2.9.1
|
||||
version: 2.9.1
|
||||
got:
|
||||
specifier: ^14.0.0
|
||||
version: 14.0.0
|
||||
|
@ -1861,8 +1861,8 @@ importers:
|
|||
specifier: workspace:^3.0.0
|
||||
version: link:../../toolkit/connector-kit
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.9.0
|
||||
version: 2.9.0
|
||||
specifier: ^2.9.1
|
||||
version: 2.9.1
|
||||
got:
|
||||
specifier: ^14.0.0
|
||||
version: 14.0.0
|
||||
|
@ -1937,8 +1937,8 @@ importers:
|
|||
specifier: workspace:^3.1.1
|
||||
version: link:../../shared
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.9.0
|
||||
version: 2.9.0
|
||||
specifier: ^2.9.1
|
||||
version: 2.9.1
|
||||
jose:
|
||||
specifier: ^5.0.0
|
||||
version: 5.2.2
|
||||
|
@ -2022,8 +2022,8 @@ importers:
|
|||
specifier: workspace:^3.1.1
|
||||
version: link:../../shared
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.9.0
|
||||
version: 2.9.0
|
||||
specifier: ^2.9.1
|
||||
version: 2.9.1
|
||||
jose:
|
||||
specifier: ^5.0.0
|
||||
version: 5.0.1
|
||||
|
@ -2101,8 +2101,8 @@ importers:
|
|||
specifier: workspace:^3.0.0
|
||||
version: link:../../toolkit/connector-kit
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.9.0
|
||||
version: 2.9.0
|
||||
specifier: ^2.9.1
|
||||
version: 2.9.1
|
||||
fast-xml-parser:
|
||||
specifier: ^4.3.6
|
||||
version: 4.3.6
|
||||
|
@ -2180,8 +2180,8 @@ importers:
|
|||
specifier: workspace:^3.0.0
|
||||
version: link:../../toolkit/connector-kit
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.9.0
|
||||
version: 2.9.0
|
||||
specifier: ^2.9.1
|
||||
version: 2.9.1
|
||||
got:
|
||||
specifier: ^14.0.0
|
||||
version: 14.0.0
|
||||
|
@ -2253,8 +2253,8 @@ importers:
|
|||
specifier: workspace:^3.0.0
|
||||
version: link:../../toolkit/connector-kit
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.9.0
|
||||
version: 2.9.0
|
||||
specifier: ^2.9.1
|
||||
version: 2.9.1
|
||||
got:
|
||||
specifier: ^14.0.0
|
||||
version: 14.0.0
|
||||
|
@ -2326,8 +2326,8 @@ importers:
|
|||
specifier: workspace:^3.0.0
|
||||
version: link:../../toolkit/connector-kit
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.9.0
|
||||
version: 2.9.0
|
||||
specifier: ^2.9.1
|
||||
version: 2.9.1
|
||||
got:
|
||||
specifier: ^14.0.0
|
||||
version: 14.0.0
|
||||
|
@ -2405,8 +2405,8 @@ importers:
|
|||
specifier: workspace:^3.0.0
|
||||
version: link:../../toolkit/connector-kit
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.9.0
|
||||
version: 2.9.0
|
||||
specifier: ^2.9.1
|
||||
version: 2.9.1
|
||||
got:
|
||||
specifier: ^14.0.0
|
||||
version: 14.0.0
|
||||
|
@ -2478,8 +2478,8 @@ importers:
|
|||
specifier: workspace:^3.0.0
|
||||
version: link:../../toolkit/connector-kit
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.9.0
|
||||
version: 2.9.0
|
||||
specifier: ^2.9.1
|
||||
version: 2.9.1
|
||||
got:
|
||||
specifier: ^14.0.0
|
||||
version: 14.0.0
|
||||
|
@ -2551,8 +2551,8 @@ importers:
|
|||
specifier: workspace:^3.0.0
|
||||
version: link:../../toolkit/connector-kit
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.9.0
|
||||
version: 2.9.0
|
||||
specifier: ^2.9.1
|
||||
version: 2.9.1
|
||||
got:
|
||||
specifier: ^14.0.0
|
||||
version: 14.0.0
|
||||
|
@ -2624,8 +2624,8 @@ importers:
|
|||
specifier: workspace:^3.0.0
|
||||
version: link:../../toolkit/connector-kit
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.9.0
|
||||
version: 2.9.0
|
||||
specifier: ^2.9.1
|
||||
version: 2.9.1
|
||||
got:
|
||||
specifier: ^14.0.0
|
||||
version: 14.0.0
|
||||
|
@ -2697,8 +2697,8 @@ importers:
|
|||
specifier: workspace:^3.0.0
|
||||
version: link:../../toolkit/connector-kit
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.9.0
|
||||
version: 2.9.0
|
||||
specifier: ^2.9.1
|
||||
version: 2.9.1
|
||||
got:
|
||||
specifier: ^14.0.0
|
||||
version: 14.0.0
|
||||
|
@ -2830,8 +2830,8 @@ importers:
|
|||
specifier: 6.0.2
|
||||
version: 6.0.2(eslint@8.57.0)(postcss@8.4.31)(prettier@3.0.0)(stylelint@15.11.0(typescript@5.3.3))(typescript@5.3.3)
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.9.0
|
||||
version: 2.9.0
|
||||
specifier: ^2.9.1
|
||||
version: 2.9.1
|
||||
'@silverhand/ts-config':
|
||||
specifier: 6.0.0
|
||||
version: 6.0.0(typescript@5.3.3)
|
||||
|
@ -3127,8 +3127,8 @@ importers:
|
|||
specifier: workspace:^3.1.1
|
||||
version: link:../shared
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.9.0
|
||||
version: 2.9.0
|
||||
specifier: ^2.9.1
|
||||
version: 2.9.1
|
||||
'@silverhand/slonik':
|
||||
specifier: 31.0.0-beta.2
|
||||
version: 31.0.0-beta.2
|
||||
|
@ -3512,8 +3512,8 @@ importers:
|
|||
specifier: 6.0.2
|
||||
version: 6.0.2(eslint@8.57.0)(postcss@8.4.31)(prettier@3.0.0)(stylelint@15.11.0(typescript@5.3.3))(typescript@5.3.3)
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.9.0
|
||||
version: 2.9.0
|
||||
specifier: ^2.9.1
|
||||
version: 2.9.1
|
||||
'@silverhand/ts-config':
|
||||
specifier: 6.0.0
|
||||
version: 6.0.0(typescript@5.3.3)
|
||||
|
@ -3714,8 +3714,8 @@ importers:
|
|||
specifier: 6.0.1
|
||||
version: 6.0.1(eslint@8.57.0)(prettier@3.0.0)(typescript@5.3.3)
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.9.0
|
||||
version: 2.9.0
|
||||
specifier: ^2.9.1
|
||||
version: 2.9.1
|
||||
'@silverhand/ts-config':
|
||||
specifier: 6.0.0
|
||||
version: 6.0.0(typescript@5.3.3)
|
||||
|
@ -3777,8 +3777,8 @@ importers:
|
|||
specifier: workspace:^1.1.0
|
||||
version: link:../toolkit/language-kit
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.9.0
|
||||
version: 2.9.0
|
||||
specifier: ^2.9.1
|
||||
version: 2.9.1
|
||||
zod:
|
||||
specifier: ^3.22.4
|
||||
version: 3.22.4
|
||||
|
@ -3811,8 +3811,8 @@ importers:
|
|||
specifier: workspace:^1.1.0
|
||||
version: link:../toolkit/language-kit
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.9.0
|
||||
version: 2.9.0
|
||||
specifier: ^2.9.1
|
||||
version: 2.9.1
|
||||
zod:
|
||||
specifier: ^3.22.4
|
||||
version: 3.22.4
|
||||
|
@ -3870,8 +3870,8 @@ importers:
|
|||
specifier: 6.0.1
|
||||
version: 6.0.1(eslint@8.57.0)(prettier@3.0.0)(typescript@5.3.3)
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.9.0
|
||||
version: 2.9.0
|
||||
specifier: ^2.9.1
|
||||
version: 2.9.1
|
||||
'@silverhand/slonik':
|
||||
specifier: 31.0.0-beta.2
|
||||
version: 31.0.0-beta.2
|
||||
|
@ -3921,8 +3921,8 @@ importers:
|
|||
packages/shared:
|
||||
dependencies:
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.9.0
|
||||
version: 2.9.0
|
||||
specifier: ^2.9.1
|
||||
version: 2.9.1
|
||||
chalk:
|
||||
specifier: ^5.0.0
|
||||
version: 5.1.2
|
||||
|
@ -3973,8 +3973,8 @@ importers:
|
|||
specifier: workspace:^1.1.0
|
||||
version: link:../language-kit
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.9.0
|
||||
version: 2.9.0
|
||||
specifier: ^2.9.1
|
||||
version: 2.9.1
|
||||
'@withtyped/client':
|
||||
specifier: ^0.8.7
|
||||
version: 0.8.7(zod@3.22.4)
|
||||
|
@ -4023,8 +4023,8 @@ importers:
|
|||
specifier: workspace:^3.1.0
|
||||
version: link:../../shared
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.9.0
|
||||
version: 2.9.0
|
||||
specifier: ^2.9.1
|
||||
version: 2.9.1
|
||||
color:
|
||||
specifier: ^4.2.3
|
||||
version: 4.2.3
|
||||
|
@ -5890,9 +5890,9 @@ packages:
|
|||
peerDependencies:
|
||||
eslint: ^8.1.0
|
||||
|
||||
'@silverhand/essentials@2.9.0':
|
||||
resolution: {integrity: sha512-n9mSO/gsLj0GRFXBRNhaQLRK6qbn6pBnKjMQdFwweKgT12ODBXpgkpXohpOBqSofnoaCQWqiDAT6xpCy/5dMIg==}
|
||||
engines: {node: ^18.12.0 || ^20.9.0, pnpm: ^8.0.0}
|
||||
'@silverhand/essentials@2.9.1':
|
||||
resolution: {integrity: sha512-rsql/ZxXMqVvt7ySDHd7xjCog4oCYg+dexxlj3veolajwjKiy/08ZtFyEtFjSEAaKbXwkWZ4TDtiNSxb7HS0yA==}
|
||||
engines: {node: ^18.12.0 || ^20.9.0, pnpm: ^9.0.0}
|
||||
|
||||
'@silverhand/slonik@31.0.0-beta.2':
|
||||
resolution: {integrity: sha512-4IM57Er5We8+hT8IY9z5La1JAGNRFZ63tp3N0XYUYTNV9fLfUXF78yT+PoW4arnf4qc+4n498bMmKgFmt/mo9Q==}
|
||||
|
@ -14691,44 +14691,44 @@ snapshots:
|
|||
|
||||
'@logto/affiliate@0.1.0':
|
||||
dependencies:
|
||||
'@silverhand/essentials': 2.9.0
|
||||
'@silverhand/essentials': 2.9.1
|
||||
tiny-cookie: 2.4.1
|
||||
|
||||
'@logto/browser@2.2.10':
|
||||
dependencies:
|
||||
'@logto/client': 2.6.6
|
||||
'@silverhand/essentials': 2.9.0
|
||||
'@silverhand/essentials': 2.9.1
|
||||
js-base64: 3.7.5
|
||||
|
||||
'@logto/client@2.6.6':
|
||||
dependencies:
|
||||
'@logto/js': 4.1.1
|
||||
'@silverhand/essentials': 2.9.0
|
||||
'@silverhand/essentials': 2.9.1
|
||||
camelcase-keys: 7.0.2
|
||||
jose: 5.2.2
|
||||
|
||||
'@logto/cloud@0.2.5-e5d8200(zod@3.22.4)':
|
||||
dependencies:
|
||||
'@silverhand/essentials': 2.9.0
|
||||
'@silverhand/essentials': 2.9.1
|
||||
'@withtyped/server': 0.13.6(zod@3.22.4)
|
||||
transitivePeerDependencies:
|
||||
- zod
|
||||
|
||||
'@logto/js@4.1.1':
|
||||
dependencies:
|
||||
'@silverhand/essentials': 2.9.0
|
||||
'@silverhand/essentials': 2.9.1
|
||||
camelcase-keys: 7.0.2
|
||||
|
||||
'@logto/node@2.4.7':
|
||||
dependencies:
|
||||
'@logto/client': 2.6.6
|
||||
'@silverhand/essentials': 2.9.0
|
||||
'@silverhand/essentials': 2.9.1
|
||||
js-base64: 3.7.5
|
||||
|
||||
'@logto/react@3.0.8(react@18.2.0)':
|
||||
dependencies:
|
||||
'@logto/browser': 2.2.10
|
||||
'@silverhand/essentials': 2.9.0
|
||||
'@silverhand/essentials': 2.9.1
|
||||
react: 18.2.0
|
||||
|
||||
'@manypkg/find-root@1.1.0':
|
||||
|
@ -15801,7 +15801,7 @@ snapshots:
|
|||
import-modules: 2.1.0
|
||||
lodash: 4.17.21
|
||||
|
||||
'@silverhand/essentials@2.9.0': {}
|
||||
'@silverhand/essentials@2.9.1': {}
|
||||
|
||||
'@silverhand/slonik@31.0.0-beta.2':
|
||||
dependencies:
|
||||
|
@ -16965,7 +16965,7 @@ snapshots:
|
|||
|
||||
'@withtyped/server@0.13.6(zod@3.22.4)':
|
||||
dependencies:
|
||||
'@silverhand/essentials': 2.9.0
|
||||
'@silverhand/essentials': 2.9.1
|
||||
'@withtyped/shared': 0.2.2
|
||||
nanoid: 4.0.2
|
||||
zod: 3.22.4
|
||||
|
|
Loading…
Reference in a new issue