mirror of
https://github.com/logto-io/logto.git
synced 2025-01-06 20:40:08 -05:00
fix: delete custom domain (#737)
* fix: delete custom domain * fix: use sql wrapper
This commit is contained in:
parent
2d9b7088a6
commit
8a48fb6225
10 changed files with 14 additions and 36 deletions
|
@ -13,7 +13,6 @@ import CardTitle from '@/components/CardTitle';
|
||||||
import FormField from '@/components/FormField';
|
import FormField from '@/components/FormField';
|
||||||
import Select from '@/components/Select';
|
import Select from '@/components/Select';
|
||||||
import TabNav, { TabNavLink } from '@/components/TabNav';
|
import TabNav, { TabNavLink } from '@/components/TabNav';
|
||||||
import TextInput from '@/components/TextInput';
|
|
||||||
import { themeStorageKey } from '@/consts';
|
import { themeStorageKey } from '@/consts';
|
||||||
import useApi, { RequestError } from '@/hooks/use-api';
|
import useApi, { RequestError } from '@/hooks/use-api';
|
||||||
import * as detailsStyles from '@/scss/details.module.scss';
|
import * as detailsStyles from '@/scss/details.module.scss';
|
||||||
|
@ -26,7 +25,6 @@ const Settings = () => {
|
||||||
const {
|
const {
|
||||||
reset,
|
reset,
|
||||||
handleSubmit,
|
handleSubmit,
|
||||||
register,
|
|
||||||
control,
|
control,
|
||||||
formState: { isSubmitting },
|
formState: { isSubmitting },
|
||||||
} = useForm<Setting>();
|
} = useForm<Setting>();
|
||||||
|
@ -66,9 +64,6 @@ const Settings = () => {
|
||||||
{data && (
|
{data && (
|
||||||
<form className={detailsStyles.body} onSubmit={onSubmit}>
|
<form className={detailsStyles.body} onSubmit={onSubmit}>
|
||||||
<div className={styles.fields}>
|
<div className={styles.fields}>
|
||||||
<FormField title="admin_console.settings.custom_domain">
|
|
||||||
<TextInput {...register('customDomain')} />
|
|
||||||
</FormField>
|
|
||||||
<FormField isRequired title="admin_console.settings.language">
|
<FormField isRequired title="admin_console.settings.language">
|
||||||
<Controller
|
<Controller
|
||||||
name="adminConsole.language"
|
name="adminConsole.language"
|
||||||
|
|
|
@ -45,7 +45,6 @@ export const mockRole: Role = {
|
||||||
|
|
||||||
export const mockSetting: Setting = {
|
export const mockSetting: Setting = {
|
||||||
id: 'foo setting',
|
id: 'foo setting',
|
||||||
customDomain: 'mock-logto.dev',
|
|
||||||
adminConsole: {
|
adminConsole: {
|
||||||
language: Language.English,
|
language: Language.English,
|
||||||
appearanceMode: AppearanceMode.SyncWithSystem,
|
appearanceMode: AppearanceMode.SyncWithSystem,
|
||||||
|
|
|
@ -73,10 +73,10 @@ export const createDatabaseCli = (dsn: string) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const seedTables = async (domain: string) => {
|
const seedTables = async () => {
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
pool.query(insertInto(managementResource, 'resources')),
|
pool.query(insertInto(managementResource, 'resources')),
|
||||||
pool.query(insertInto(createDefaultSetting(domain), 'settings')),
|
pool.query(insertInto(createDefaultSetting(), 'settings')),
|
||||||
pool.query(insertInto(defaultSignInExperience, 'sign_in_experiences')),
|
pool.query(insertInto(defaultSignInExperience, 'sign_in_experiences')),
|
||||||
]);
|
]);
|
||||||
console.log(`${chalk.blue('[seed-tables]')} Seed tables succeeded.`);
|
console.log(`${chalk.blue('[seed-tables]')} Seed tables succeeded.`);
|
||||||
|
|
|
@ -55,7 +55,7 @@ const inquireForLogtoDsn = async (key: string): Promise<[Optional<string>, boole
|
||||||
return [dsn, true];
|
return [dsn, true];
|
||||||
};
|
};
|
||||||
|
|
||||||
const createPoolByEnv = async (isTest: boolean, localhostUrl: string) => {
|
const createPoolByEnv = async (isTest: boolean) => {
|
||||||
// Database connection is disabled in unit test environment
|
// Database connection is disabled in unit test environment
|
||||||
if (isTest) {
|
if (isTest) {
|
||||||
return;
|
return;
|
||||||
|
@ -82,14 +82,8 @@ const createPoolByEnv = async (isTest: boolean, localhostUrl: string) => {
|
||||||
const cli = createDatabaseCli(dsn);
|
const cli = createDatabaseCli(dsn);
|
||||||
|
|
||||||
if (needsSeed) {
|
if (needsSeed) {
|
||||||
const domain = await inquirer.prompt({
|
|
||||||
name: 'value',
|
|
||||||
default: localhostUrl,
|
|
||||||
message: 'Enter your domain for Logto:',
|
|
||||||
});
|
|
||||||
|
|
||||||
await cli.createTables();
|
await cli.createTables();
|
||||||
await cli.seedTables(domain.value);
|
await cli.seedTables();
|
||||||
}
|
}
|
||||||
|
|
||||||
appendDotEnv(key, dsn);
|
appendDotEnv(key, dsn);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { conditionalString, getEnv, Optional } from '@silverhand/essentials';
|
import { getEnv, Optional } from '@silverhand/essentials';
|
||||||
import { DatabasePool } from 'slonik';
|
import { DatabasePool } from 'slonik';
|
||||||
|
|
||||||
import createPoolByEnv from './create-pool-by-env';
|
import createPoolByEnv from './create-pool-by-env';
|
||||||
|
@ -59,10 +59,7 @@ function createEnvSet() {
|
||||||
|
|
||||||
load: async () => {
|
load: async () => {
|
||||||
values = await loadEnvValues();
|
values = await loadEnvValues();
|
||||||
pool = await createPoolByEnv(
|
pool = await createPoolByEnv(values.isTest);
|
||||||
values.isTest,
|
|
||||||
`http${conditionalString(values.isHttpsEnabled && 's')}://localhost:${values.port}`
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,22 +40,24 @@ describe('setting query', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('updateSetting', async () => {
|
it('updateSetting', async () => {
|
||||||
const customDomain = 'logto.io';
|
const { adminConsole } = mockSetting;
|
||||||
|
|
||||||
const expectSql = sql`
|
const expectSql = sql`
|
||||||
update ${table}
|
update ${table}
|
||||||
set ${fields.customDomain}=$1
|
set
|
||||||
|
${fields.adminConsole}=
|
||||||
|
coalesce("admin_console",'{}'::jsonb)|| $1
|
||||||
where ${fields.id}=$2
|
where ${fields.id}=$2
|
||||||
returning *
|
returning *
|
||||||
`;
|
`;
|
||||||
|
|
||||||
mockQuery.mockImplementationOnce(async (sql, values) => {
|
mockQuery.mockImplementationOnce(async (sql, values) => {
|
||||||
expectSqlAssert(sql, expectSql.sql);
|
expectSqlAssert(sql, expectSql.sql);
|
||||||
expect(values).toEqual([customDomain, defaultSettingId]);
|
expect(values).toEqual([JSON.stringify(adminConsole), defaultSettingId]);
|
||||||
|
|
||||||
return createMockQueryResult([dbvalue]);
|
return createMockQueryResult([dbvalue]);
|
||||||
});
|
});
|
||||||
|
|
||||||
await expect(updateSetting({ customDomain })).resolves.toEqual(dbvalue);
|
await expect(updateSetting({ adminConsole })).resolves.toEqual(dbvalue);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -26,17 +26,14 @@ describe('settings routes', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('PATCH /settings', async () => {
|
it('PATCH /settings', async () => {
|
||||||
const customDomain = 'silverhand-logto.io';
|
|
||||||
const { adminConsole } = mockSetting;
|
const { adminConsole } = mockSetting;
|
||||||
|
|
||||||
const response = await roleRequester.patch('/settings').send({
|
const response = await roleRequester.patch('/settings').send({
|
||||||
customDomain,
|
|
||||||
adminConsole,
|
adminConsole,
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(response.status).toEqual(200);
|
expect(response.status).toEqual(200);
|
||||||
expect(response.body).toEqual({
|
expect(response.body).toEqual({
|
||||||
customDomain,
|
|
||||||
adminConsole,
|
adminConsole,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -11,19 +11,16 @@ import {
|
||||||
|
|
||||||
export type CreateSetting = {
|
export type CreateSetting = {
|
||||||
id: string;
|
id: string;
|
||||||
customDomain?: string | null;
|
|
||||||
adminConsole: AdminConsoleConfig;
|
adminConsole: AdminConsoleConfig;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type Setting = {
|
export type Setting = {
|
||||||
id: string;
|
id: string;
|
||||||
customDomain: string | null;
|
|
||||||
adminConsole: AdminConsoleConfig;
|
adminConsole: AdminConsoleConfig;
|
||||||
};
|
};
|
||||||
|
|
||||||
const createGuard: Guard<CreateSetting> = z.object({
|
const createGuard: Guard<CreateSetting> = z.object({
|
||||||
id: z.string(),
|
id: z.string(),
|
||||||
customDomain: z.string().nullable().optional(),
|
|
||||||
adminConsole: adminConsoleConfigGuard,
|
adminConsole: adminConsoleConfigGuard,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -32,9 +29,8 @@ export const Settings: GeneratedSchema<CreateSetting> = Object.freeze({
|
||||||
tableSingular: 'setting',
|
tableSingular: 'setting',
|
||||||
fields: {
|
fields: {
|
||||||
id: 'id',
|
id: 'id',
|
||||||
customDomain: 'custom_domain',
|
|
||||||
adminConsole: 'admin_console',
|
adminConsole: 'admin_console',
|
||||||
},
|
},
|
||||||
fieldKeys: ['id', 'customDomain', 'adminConsole'],
|
fieldKeys: ['id', 'adminConsole'],
|
||||||
createGuard,
|
createGuard,
|
||||||
});
|
});
|
||||||
|
|
|
@ -5,10 +5,9 @@ import { AppearanceMode } from '../foundations';
|
||||||
|
|
||||||
export const defaultSettingId = 'default';
|
export const defaultSettingId = 'default';
|
||||||
|
|
||||||
export const createDefaultSetting = (customDomain: string): Readonly<CreateSetting> =>
|
export const createDefaultSetting = (): Readonly<CreateSetting> =>
|
||||||
Object.freeze({
|
Object.freeze({
|
||||||
id: defaultSettingId,
|
id: defaultSettingId,
|
||||||
customDomain,
|
|
||||||
adminConsole: {
|
adminConsole: {
|
||||||
language: Language.English,
|
language: Language.English,
|
||||||
appearanceMode: AppearanceMode.SyncWithSystem,
|
appearanceMode: AppearanceMode.SyncWithSystem,
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
create table settings (
|
create table settings (
|
||||||
id varchar(21) not null,
|
id varchar(21) not null,
|
||||||
custom_domain text,
|
|
||||||
admin_console jsonb /* @use AdminConsoleConfig */ not null,
|
admin_console jsonb /* @use AdminConsoleConfig */ not null,
|
||||||
primary key (id)
|
primary key (id)
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in a new issue