Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: outdated config schema #1769

Merged
merged 1 commit into from
Dec 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion data/default.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"schemaVersion": 1,
"schemaVersion": 2,
"configProperties": {
"name": "default"
},
Expand Down
21 changes: 20 additions & 1 deletion src/components/Onboarding/onboarding-steps.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,31 @@ import { useState } from 'react';
import { StepCreateAccount } from './step-create-account';
import { StepOnboardingFinished } from './step-onboarding-finished';
import { StepUpdatePathMappings } from './step-update-path-mappings';
import { api } from '~/utils/api';

export const OnboardingSteps = ({ isUpdate }: { isUpdate: boolean }) => {
const maximumSteps = isUpdate ? 3 : 2;

const [currentStep, setCurrentStep] = useState(0);
const nextStep = () => setCurrentStep((current) => (current < 3 ? current + 1 : current));

const nextStep = () => setCurrentStep((current) => {
const newValue = (current < maximumSteps ? current + 1 : current);

if (currentStep + 1 >= maximumSteps) {
onFinishOnboarding();
}

return newValue;
});

const prevStep = () => setCurrentStep((current) => (current > 0 ? current - 1 : current));

const { mutate: mutateConfigSchemaVersion } = api.config.updateConfigurationSchemaToLatest.useMutation();

const onFinishOnboarding = () => {
mutateConfigSchemaVersion();
};

return (
<Stack p="lg">
<Stepper
Expand Down
38 changes: 29 additions & 9 deletions src/server/api/routers/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ import { boardCustomizationSchema } from '~/validations/boards';
import { IRssWidget } from '~/widgets/rss/RssWidgetTile';

import { adminProcedure, createTRPCRouter, publicProcedure } from '../trpc';
import { db } from '~/server/db';
import { users } from '~/server/db/schema';
import { sql } from 'drizzle-orm';

export const configNameSchema = z.string().regex(/^[a-zA-Z0-9-_]+$/);

Expand All @@ -20,14 +23,14 @@ export const configRouter = createTRPCRouter({
.input(
z.object({
name: configNameSchema,
})
}),
)
.mutation(async ({ input }) => {
if (input.name.toLowerCase() === 'default') {
Consola.error("Rejected config deletion because default configuration can't be deleted");
Consola.error('Rejected config deletion because default configuration can\'t be deleted');
throw new TRPCError({
code: 'FORBIDDEN',
message: "Default config can't be deleted",
message: 'Default config can\'t be deleted',
});
}

Expand All @@ -44,7 +47,7 @@ export const configRouter = createTRPCRouter({
// If the target is not in the list of files, return an error
if (!matchedFile) {
Consola.error(
`Rejected config deletion request because config name '${input.name}' was not included in present configurations`
`Rejected config deletion request because config name '${input.name}' was not included in present configurations`,
);
throw new TRPCError({
code: 'NOT_FOUND',
Expand All @@ -64,7 +67,7 @@ export const configRouter = createTRPCRouter({
z.object({
name: configNameSchema,
config: z.custom<ConfigType>((x) => !!x && typeof x === 'object'),
})
}),
)
.mutation(async ({ input }) => {
Consola.info(`Saving updated configuration of '${input.name}' config.`);
Expand Down Expand Up @@ -96,16 +99,16 @@ export const configRouter = createTRPCRouter({
}

const previousApp = previousConfig.apps.find(
(previousApp) => previousApp.id === app.id
(previousApp) => previousApp.id === app.id,
);

const previousProperty = previousApp?.integration?.properties.find(
(previousProperty) => previousProperty.field === property.field
(previousProperty) => previousProperty.field === property.field,
);

if (property.value !== undefined && property.value !== null) {
Consola.info(
'Detected credential change of private secret. Value will be overwritten in configuration'
'Detected credential change of private secret. Value will be overwritten in configuration',
);
return {
field: property.field,
Expand Down Expand Up @@ -165,7 +168,7 @@ export const configRouter = createTRPCRouter({
.input(
z.object({
name: configNameSchema,
})
}),
)
.query(async ({ ctx, input }) => {
if (!configExists(input.name)) {
Expand Down Expand Up @@ -223,4 +226,21 @@ export const configRouter = createTRPCRouter({
const targetPath = path.join('data/configs', `${input.name}.json`);
fs.writeFileSync(targetPath, JSON.stringify(newConfig, null, 2), 'utf8');
}),
// publicProcedure is not optimal, but should be fince, since there is no input and output data nor can you break the config
updateConfigurationSchemaToLatest: publicProcedure.mutation(async () => {
Meierschlumpf marked this conversation as resolved.
Show resolved Hide resolved
const files = fs.readdirSync('./data/configs').filter((file) => file.endsWith('.json'));

console.log('updating the schema version of', files.length, 'configurations');

for (const file of files) {
const name = file.replace('.json', '');
const config = await getFrontendConfig(name);

config.schemaVersion = 2;
const targetPath = `data/configs/${name}.json`;
fs.writeFileSync(targetPath, JSON.stringify(config, null, 2), 'utf8');

console.log('updated', name, 'to schema version', config.schemaVersion);
}
}),
});
Loading