fix(dashboard): mutation
This commit is contained in:
parent
0049e1380b
commit
ac416bfc7b
|
@ -15,7 +15,7 @@ export default function Dashboard() {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<h1>Hey 👋,</h1>
|
<h1>Hey 👋,</h1>
|
||||||
<p>Thank you for joining authorizer demo app.</p>
|
<p>Thank you for using authorizer.</p>
|
||||||
<p>
|
<p>
|
||||||
Your email address is{' '}
|
Your email address is{' '}
|
||||||
<a href={`mailto:${user?.email}`} style={{ color: '#3B82F6' }}>
|
<a href={`mailto:${user?.email}`} style={{ color: '#3B82F6' }}>
|
||||||
|
|
2304
dashboard/package-lock.json
generated
2304
dashboard/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
|
@ -12,6 +12,7 @@ const queryClient = createClient({
|
||||||
credentials: 'include',
|
credentials: 'include',
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
requestPolicy: 'network-only',
|
||||||
});
|
});
|
||||||
|
|
||||||
const theme = extendTheme({
|
const theme = extendTheme({
|
||||||
|
|
|
@ -282,7 +282,7 @@ const InputField = ({
|
||||||
<Code h="75%">Off</Code>
|
<Code h="75%">Off</Code>
|
||||||
<Switch
|
<Switch
|
||||||
size="md"
|
size="md"
|
||||||
isChecked={!envVariables[inputType]}
|
isChecked={envVariables[inputType]}
|
||||||
onChange={() => {
|
onChange={() => {
|
||||||
setEnvVariables({
|
setEnvVariables({
|
||||||
...envVariables,
|
...envVariables,
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import React, { ReactNode } from 'react';
|
import React, { ReactNode } from 'react';
|
||||||
import {
|
import {
|
||||||
IconButton,
|
IconButton,
|
||||||
Avatar,
|
|
||||||
Box,
|
Box,
|
||||||
CloseButton,
|
CloseButton,
|
||||||
Flex,
|
Flex,
|
||||||
|
@ -21,9 +20,7 @@ import {
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import {
|
import {
|
||||||
FiHome,
|
FiHome,
|
||||||
FiTrendingUp,
|
FiCode,
|
||||||
FiCompass,
|
|
||||||
FiStar,
|
|
||||||
FiSettings,
|
FiSettings,
|
||||||
FiMenu,
|
FiMenu,
|
||||||
FiUser,
|
FiUser,
|
||||||
|
@ -90,6 +87,17 @@ export const Sidebar = ({ onClose, ...rest }: SidebarProps) => {
|
||||||
</NavItem>
|
</NavItem>
|
||||||
</NavLink>
|
</NavLink>
|
||||||
))}
|
))}
|
||||||
|
|
||||||
|
<Link
|
||||||
|
href="/playground"
|
||||||
|
target="_blank"
|
||||||
|
style={{
|
||||||
|
textDecoration: 'none',
|
||||||
|
}}
|
||||||
|
_focus={{ _boxShadow: 'none' }}
|
||||||
|
>
|
||||||
|
<NavItem icon={FiCode}>API Playground</NavItem>
|
||||||
|
</Link>
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -100,11 +108,6 @@ interface NavItemProps extends FlexProps {
|
||||||
}
|
}
|
||||||
export const NavItem = ({ icon, children, ...rest }: NavItemProps) => {
|
export const NavItem = ({ icon, children, ...rest }: NavItemProps) => {
|
||||||
return (
|
return (
|
||||||
<Link
|
|
||||||
href="#"
|
|
||||||
style={{ textDecoration: 'none' }}
|
|
||||||
_focus={{ boxShadow: 'none' }}
|
|
||||||
>
|
|
||||||
<Flex
|
<Flex
|
||||||
align="center"
|
align="center"
|
||||||
p="3"
|
p="3"
|
||||||
|
@ -130,7 +133,6 @@ export const NavItem = ({ icon, children, ...rest }: NavItemProps) => {
|
||||||
)}
|
)}
|
||||||
{children}
|
{children}
|
||||||
</Flex>
|
</Flex>
|
||||||
</Link>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React from 'react';
|
import React, { useEffect } from 'react';
|
||||||
import {
|
import {
|
||||||
Box,
|
Box,
|
||||||
Divider,
|
Divider,
|
||||||
|
@ -10,13 +10,13 @@ import {
|
||||||
Input,
|
Input,
|
||||||
InputGroup,
|
InputGroup,
|
||||||
InputRightElement,
|
InputRightElement,
|
||||||
|
useToast,
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import { useClient } from 'urql';
|
import { useClient } from 'urql';
|
||||||
import {
|
import {
|
||||||
FaGoogle,
|
FaGoogle,
|
||||||
FaGithub,
|
FaGithub,
|
||||||
FaFacebookF,
|
FaFacebookF,
|
||||||
FaUndo,
|
|
||||||
FaSave,
|
FaSave,
|
||||||
FaRegEyeSlash,
|
FaRegEyeSlash,
|
||||||
FaRegEye,
|
FaRegEye,
|
||||||
|
@ -33,7 +33,7 @@ import {
|
||||||
SwitchInputType,
|
SwitchInputType,
|
||||||
} from '../constants';
|
} from '../constants';
|
||||||
import { UpdateEnvVariables } from '../graphql/mutation';
|
import { UpdateEnvVariables } from '../graphql/mutation';
|
||||||
import { getObjectDiff } from '../utils';
|
import { getObjectDiff, capitalizeFirstLetter } from '../utils';
|
||||||
|
|
||||||
interface envVarTypes {
|
interface envVarTypes {
|
||||||
GOOGLE_CLIENT_ID: string;
|
GOOGLE_CLIENT_ID: string;
|
||||||
|
@ -71,13 +71,14 @@ interface envVarTypes {
|
||||||
|
|
||||||
export default function Environment() {
|
export default function Environment() {
|
||||||
const client = useClient();
|
const client = useClient();
|
||||||
|
const toast = useToast();
|
||||||
const [adminSecret, setAdminSecret] = React.useState<
|
const [adminSecret, setAdminSecret] = React.useState<
|
||||||
Record<string, string | boolean>
|
Record<string, string | boolean>
|
||||||
>({
|
>({
|
||||||
value: '',
|
value: '',
|
||||||
disableInputField: true,
|
disableInputField: true,
|
||||||
});
|
});
|
||||||
const [loading, setLoading] = React.useState<boolean>(false);
|
const [loading, setLoading] = React.useState<boolean>(true);
|
||||||
const [envVariables, setEnvVariables] = React.useState<envVarTypes>({
|
const [envVariables, setEnvVariables] = React.useState<envVarTypes>({
|
||||||
GOOGLE_CLIENT_ID: '',
|
GOOGLE_CLIENT_ID: '',
|
||||||
GOOGLE_CLIENT_SECRET: '',
|
GOOGLE_CLIENT_SECRET: '',
|
||||||
|
@ -111,39 +112,7 @@ export default function Environment() {
|
||||||
DATABASE_TYPE: '',
|
DATABASE_TYPE: '',
|
||||||
DATABASE_URL: '',
|
DATABASE_URL: '',
|
||||||
});
|
});
|
||||||
const [oldEnvVariables, setOldEnvVariables] = React.useState<envVarTypes>({
|
|
||||||
GOOGLE_CLIENT_ID: '',
|
|
||||||
GOOGLE_CLIENT_SECRET: '',
|
|
||||||
GITHUB_CLIENT_ID: '',
|
|
||||||
GITHUB_CLIENT_SECRET: '',
|
|
||||||
FACEBOOK_CLIENT_ID: '',
|
|
||||||
FACEBOOK_CLIENT_SECRET: '',
|
|
||||||
ROLES: [],
|
|
||||||
DEFAULT_ROLES: [],
|
|
||||||
PROTECTED_ROLES: [],
|
|
||||||
JWT_TYPE: '',
|
|
||||||
JWT_SECRET: '',
|
|
||||||
JWT_ROLE_CLAIM: '',
|
|
||||||
REDIS_URL: '',
|
|
||||||
SMTP_HOST: '',
|
|
||||||
SMTP_PORT: '',
|
|
||||||
SMTP_USERNAME: '',
|
|
||||||
SMTP_PASSWORD: '',
|
|
||||||
SENDER_EMAIL: '',
|
|
||||||
ALLOWED_ORIGINS: [],
|
|
||||||
ORGANIZATION_NAME: '',
|
|
||||||
ORGANIZATION_LOGO: '',
|
|
||||||
CUSTOM_ACCESS_TOKEN_SCRIPT: '',
|
|
||||||
ADMIN_SECRET: '',
|
|
||||||
DISABLE_LOGIN_PAGE: false,
|
|
||||||
DISABLE_MAGIC_LINK_LOGIN: false,
|
|
||||||
DISABLE_EMAIL_VERIFICATION: false,
|
|
||||||
DISABLE_BASIC_AUTHENTICATION: false,
|
|
||||||
OLD_ADMIN_SECRET: '',
|
|
||||||
DATABASE_NAME: '',
|
|
||||||
DATABASE_TYPE: '',
|
|
||||||
DATABASE_URL: '',
|
|
||||||
});
|
|
||||||
const [fieldVisibility, setFieldVisibility] = React.useState<
|
const [fieldVisibility, setFieldVisibility] = React.useState<
|
||||||
Record<string, boolean>
|
Record<string, boolean>
|
||||||
>({
|
>({
|
||||||
|
@ -156,34 +125,32 @@ export default function Environment() {
|
||||||
OLD_ADMIN_SECRET: false,
|
OLD_ADMIN_SECRET: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
const updateHandler = async () => {
|
useEffect(() => {
|
||||||
setLoading(true);
|
let isMounted = true;
|
||||||
|
async function getData() {
|
||||||
const {
|
const {
|
||||||
data: { _env: envData },
|
data: { _env: envData },
|
||||||
} = await client.query(EnvVariablesQuery).toPromise();
|
} = await client.query(EnvVariablesQuery).toPromise();
|
||||||
if (envData) {
|
|
||||||
|
if (isMounted) {
|
||||||
|
setLoading(false);
|
||||||
setEnvVariables({
|
setEnvVariables({
|
||||||
...envVariables,
|
|
||||||
...envData,
|
...envData,
|
||||||
ADMIN_SECRET: '',
|
|
||||||
OLD_ADMIN_SECRET: envData.ADMIN_SECRET,
|
OLD_ADMIN_SECRET: envData.ADMIN_SECRET,
|
||||||
});
|
|
||||||
setOldEnvVariables({
|
|
||||||
...envVariables,
|
|
||||||
...envData,
|
|
||||||
ADMIN_SECRET: '',
|
ADMIN_SECRET: '',
|
||||||
OLD_ADMIN_SECRET: envData.ADMIN_SECRET,
|
|
||||||
});
|
});
|
||||||
}
|
|
||||||
setAdminSecret({
|
setAdminSecret({
|
||||||
value: '',
|
value: '',
|
||||||
disableInputField: true,
|
disableInputField: true,
|
||||||
});
|
});
|
||||||
setLoading(false);
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
React.useEffect(() => {
|
getData();
|
||||||
updateHandler();
|
|
||||||
|
return () => {
|
||||||
|
isMounted = false;
|
||||||
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const validateAdminSecretHandler = (event: any) => {
|
const validateAdminSecretHandler = (event: any) => {
|
||||||
|
@ -207,7 +174,11 @@ export default function Environment() {
|
||||||
|
|
||||||
const saveHandler = async () => {
|
const saveHandler = async () => {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
const diff = getObjectDiff(envVariables, oldEnvVariables);
|
const {
|
||||||
|
data: { _env: envData },
|
||||||
|
} = await client.query(EnvVariablesQuery).toPromise();
|
||||||
|
|
||||||
|
const diff = getObjectDiff(envVariables, envData);
|
||||||
const updatedEnvVariables = diff.reduce(
|
const updatedEnvVariables = diff.reduce(
|
||||||
(acc: any, property: string) => ({
|
(acc: any, property: string) => ({
|
||||||
...acc,
|
...acc,
|
||||||
|
@ -216,24 +187,57 @@ export default function Environment() {
|
||||||
}),
|
}),
|
||||||
{}
|
{}
|
||||||
);
|
);
|
||||||
if (diff.includes(HiddenInputType.ADMIN_SECRET)) {
|
if (
|
||||||
updatedEnvVariables[HiddenInputType.OLD_ADMIN_SECRET] =
|
updatedEnvVariables[HiddenInputType.ADMIN_SECRET] === '' ||
|
||||||
// @ts-ignore
|
updatedEnvVariables[HiddenInputType.OLD_ADMIN_SECRET] !==
|
||||||
envVariables[HiddenInputType.OLD_ADMIN_SECRET];
|
envData.ADMIN_SECRET
|
||||||
|
) {
|
||||||
|
delete updatedEnvVariables.OLD_ADMIN_SECRET;
|
||||||
|
delete updatedEnvVariables.ADMIN_SECRET;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
delete updatedEnvVariables.DATABASE_URL;
|
||||||
|
delete updatedEnvVariables.DATABASE_TYPE;
|
||||||
|
delete updatedEnvVariables.DATABASE_NAME;
|
||||||
|
|
||||||
const res = await client
|
const res = await client
|
||||||
.mutation(UpdateEnvVariables, { params: envVariables })
|
.mutation(UpdateEnvVariables, { params: updatedEnvVariables })
|
||||||
.toPromise();
|
.toPromise();
|
||||||
console.log('res ==>> ', res);
|
|
||||||
updateHandler();
|
setLoading(false);
|
||||||
|
|
||||||
|
if (res.error) {
|
||||||
|
toast({
|
||||||
|
title: capitalizeFirstLetter(res.error.message),
|
||||||
|
isClosable: true,
|
||||||
|
status: 'error',
|
||||||
|
position: 'bottom-right',
|
||||||
|
});
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setAdminSecret({
|
||||||
|
value: '',
|
||||||
|
disableInputField: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
toast({
|
||||||
|
title: `Successfully updated ${
|
||||||
|
Object.keys(updatedEnvVariables).length
|
||||||
|
} variables`,
|
||||||
|
isClosable: true,
|
||||||
|
status: 'success',
|
||||||
|
position: 'bottom-right',
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box m="5" p="5" bg="white" rounded="md">
|
<Box m="5" py="5" px="10" bg="white" rounded="md">
|
||||||
<Text fontSize="md" paddingTop="2%">
|
<Text fontSize="md" paddingTop="2%" fontWeight="bold">
|
||||||
Social Media Logins
|
Social Media Logins
|
||||||
</Text>
|
</Text>
|
||||||
<Stack spacing={6} padding="3%">
|
<Stack spacing={6} padding="2% 0%">
|
||||||
<Flex>
|
<Flex>
|
||||||
<Center
|
<Center
|
||||||
w="50px"
|
w="50px"
|
||||||
|
@ -320,10 +324,10 @@ export default function Environment() {
|
||||||
</Flex>
|
</Flex>
|
||||||
</Stack>
|
</Stack>
|
||||||
<Divider marginTop="2%" marginBottom="2%" />
|
<Divider marginTop="2%" marginBottom="2%" />
|
||||||
<Text fontSize="md" paddingTop="2%">
|
<Text fontSize="md" paddingTop="2%" fontWeight="bold">
|
||||||
Roles
|
Roles
|
||||||
</Text>
|
</Text>
|
||||||
<Stack spacing={6} padding="3% 5%">
|
<Stack spacing={6} padding="2% 0%">
|
||||||
<Flex>
|
<Flex>
|
||||||
<Flex w="30%" justifyContent="start" alignItems="center">
|
<Flex w="30%" justifyContent="start" alignItems="center">
|
||||||
<Text fontSize="sm">Roles:</Text>
|
<Text fontSize="sm">Roles:</Text>
|
||||||
|
@ -362,10 +366,10 @@ export default function Environment() {
|
||||||
</Flex>
|
</Flex>
|
||||||
</Stack>
|
</Stack>
|
||||||
<Divider marginTop="2%" marginBottom="2%" />
|
<Divider marginTop="2%" marginBottom="2%" />
|
||||||
<Text fontSize="md" paddingTop="2%">
|
<Text fontSize="md" paddingTop="2%" fontWeight="bold">
|
||||||
JWT Configurations
|
JWT (JSON Web Tokens) Configurations
|
||||||
</Text>
|
</Text>
|
||||||
<Stack spacing={6} padding="3% 5%">
|
<Stack spacing={6} padding="2% 0%">
|
||||||
<Flex>
|
<Flex>
|
||||||
<Flex w="30%" justifyContent="start" alignItems="center">
|
<Flex w="30%" justifyContent="start" alignItems="center">
|
||||||
<Text fontSize="sm">JWT Type:</Text>
|
<Text fontSize="sm">JWT Type:</Text>
|
||||||
|
@ -417,10 +421,10 @@ export default function Environment() {
|
||||||
</Flex>
|
</Flex>
|
||||||
</Stack>
|
</Stack>
|
||||||
<Divider marginTop="2%" marginBottom="2%" />
|
<Divider marginTop="2%" marginBottom="2%" />
|
||||||
<Text fontSize="md" paddingTop="2%">
|
<Text fontSize="md" paddingTop="2%" fontWeight="bold">
|
||||||
Session Storage
|
Session Storage
|
||||||
</Text>
|
</Text>
|
||||||
<Stack spacing={6} padding="3% 5%">
|
<Stack spacing={6} padding="2% 0%">
|
||||||
<Flex>
|
<Flex>
|
||||||
<Flex w="30%" justifyContent="start" alignItems="center">
|
<Flex w="30%" justifyContent="start" alignItems="center">
|
||||||
<Text fontSize="sm">Redis URL:</Text>
|
<Text fontSize="sm">Redis URL:</Text>
|
||||||
|
@ -435,10 +439,10 @@ export default function Environment() {
|
||||||
</Flex>
|
</Flex>
|
||||||
</Stack>
|
</Stack>
|
||||||
<Divider marginTop="2%" marginBottom="2%" />
|
<Divider marginTop="2%" marginBottom="2%" />
|
||||||
<Text fontSize="md" paddingTop="2%">
|
<Text fontSize="md" paddingTop="2%" fontWeight="bold">
|
||||||
Email Configurations
|
Email Configurations
|
||||||
</Text>
|
</Text>
|
||||||
<Stack spacing={6} padding="3% 5%">
|
<Stack spacing={6} padding="2% 0%">
|
||||||
<Flex>
|
<Flex>
|
||||||
<Flex w="30%" justifyContent="start" alignItems="center">
|
<Flex w="30%" justifyContent="start" alignItems="center">
|
||||||
<Text fontSize="sm">SMTP Host:</Text>
|
<Text fontSize="sm">SMTP Host:</Text>
|
||||||
|
@ -503,10 +507,10 @@ export default function Environment() {
|
||||||
</Flex>
|
</Flex>
|
||||||
</Stack>
|
</Stack>
|
||||||
<Divider marginTop="2%" marginBottom="2%" />
|
<Divider marginTop="2%" marginBottom="2%" />
|
||||||
<Text fontSize="md" paddingTop="2%">
|
<Text fontSize="md" paddingTop="2%" fontWeight="bold">
|
||||||
White Listing
|
White Listing
|
||||||
</Text>
|
</Text>
|
||||||
<Stack spacing={6} padding="3% 5%">
|
<Stack spacing={6} padding="2% 0%">
|
||||||
<Flex>
|
<Flex>
|
||||||
<Flex w="30%" justifyContent="start" alignItems="center">
|
<Flex w="30%" justifyContent="start" alignItems="center">
|
||||||
<Text fontSize="sm">Allowed Origins:</Text>
|
<Text fontSize="sm">Allowed Origins:</Text>
|
||||||
|
@ -521,10 +525,10 @@ export default function Environment() {
|
||||||
</Flex>
|
</Flex>
|
||||||
</Stack>
|
</Stack>
|
||||||
<Divider marginTop="2%" marginBottom="2%" />
|
<Divider marginTop="2%" marginBottom="2%" />
|
||||||
<Text fontSize="md" paddingTop="2%">
|
<Text fontSize="md" paddingTop="2%" fontWeight="bold">
|
||||||
Organization Information
|
Organization Information
|
||||||
</Text>
|
</Text>
|
||||||
<Stack spacing={6} padding="3% 5%">
|
<Stack spacing={6} padding="2% 0%">
|
||||||
<Flex>
|
<Flex>
|
||||||
<Flex w="30%" justifyContent="start" alignItems="center">
|
<Flex w="30%" justifyContent="start" alignItems="center">
|
||||||
<Text fontSize="sm">Organization Name:</Text>
|
<Text fontSize="sm">Organization Name:</Text>
|
||||||
|
@ -551,10 +555,10 @@ export default function Environment() {
|
||||||
</Flex>
|
</Flex>
|
||||||
</Stack>
|
</Stack>
|
||||||
<Divider marginTop="2%" marginBottom="2%" />
|
<Divider marginTop="2%" marginBottom="2%" />
|
||||||
<Text fontSize="md" paddingTop="2%">
|
<Text fontSize="md" paddingTop="2%" fontWeight="bold">
|
||||||
Custom Scripts
|
Custom Scripts
|
||||||
</Text>
|
</Text>
|
||||||
<Stack spacing={6} padding="3% 5%">
|
<Stack spacing={6} padding="2% 0%">
|
||||||
<Flex>
|
<Flex>
|
||||||
<Center w="100%">
|
<Center w="100%">
|
||||||
<InputField
|
<InputField
|
||||||
|
@ -568,13 +572,13 @@ export default function Environment() {
|
||||||
</Flex>
|
</Flex>
|
||||||
</Stack>
|
</Stack>
|
||||||
<Divider marginTop="2%" marginBottom="2%" />
|
<Divider marginTop="2%" marginBottom="2%" />
|
||||||
<Text fontSize="md" paddingTop="2%">
|
<Text fontSize="md" paddingTop="2%" fontWeight="bold">
|
||||||
Disable Features
|
Disable Features
|
||||||
</Text>
|
</Text>
|
||||||
<Stack spacing={6} padding="3% 5%">
|
<Stack spacing={6} padding="2% 0%">
|
||||||
<Flex>
|
<Flex>
|
||||||
<Flex w="30%" justifyContent="start" alignItems="center">
|
<Flex w="30%" justifyContent="start" alignItems="center">
|
||||||
<Text fontSize="sm">Login Page:</Text>
|
<Text fontSize="sm">Disable Login Page:</Text>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Flex justifyContent="start" w="70%">
|
<Flex justifyContent="start" w="70%">
|
||||||
<InputField
|
<InputField
|
||||||
|
@ -586,19 +590,7 @@ export default function Environment() {
|
||||||
</Flex>
|
</Flex>
|
||||||
<Flex>
|
<Flex>
|
||||||
<Flex w="30%" justifyContent="start" alignItems="center">
|
<Flex w="30%" justifyContent="start" alignItems="center">
|
||||||
<Text fontSize="sm">Magic Login Link:</Text>
|
<Text fontSize="sm">Disable Email Verification:</Text>
|
||||||
</Flex>
|
|
||||||
<Flex justifyContent="start" w="70%">
|
|
||||||
<InputField
|
|
||||||
envVariables={envVariables}
|
|
||||||
setEnvVariables={setEnvVariables}
|
|
||||||
inputType={SwitchInputType.DISABLE_MAGIC_LINK_LOGIN}
|
|
||||||
/>
|
|
||||||
</Flex>
|
|
||||||
</Flex>
|
|
||||||
<Flex>
|
|
||||||
<Flex w="30%" justifyContent="start" alignItems="center">
|
|
||||||
<Text fontSize="sm">Email Verification:</Text>
|
|
||||||
</Flex>
|
</Flex>
|
||||||
<Flex justifyContent="start" w="70%">
|
<Flex justifyContent="start" w="70%">
|
||||||
<InputField
|
<InputField
|
||||||
|
@ -610,7 +602,19 @@ export default function Environment() {
|
||||||
</Flex>
|
</Flex>
|
||||||
<Flex>
|
<Flex>
|
||||||
<Flex w="30%" justifyContent="start" alignItems="center">
|
<Flex w="30%" justifyContent="start" alignItems="center">
|
||||||
<Text fontSize="sm">Basic Authentication:</Text>
|
<Text fontSize="sm">Disable Magic Login Link:</Text>
|
||||||
|
</Flex>
|
||||||
|
<Flex justifyContent="start" w="70%">
|
||||||
|
<InputField
|
||||||
|
envVariables={envVariables}
|
||||||
|
setEnvVariables={setEnvVariables}
|
||||||
|
inputType={SwitchInputType.DISABLE_MAGIC_LINK_LOGIN}
|
||||||
|
/>
|
||||||
|
</Flex>
|
||||||
|
</Flex>
|
||||||
|
<Flex>
|
||||||
|
<Flex w="30%" justifyContent="start" alignItems="center">
|
||||||
|
<Text fontSize="sm">Disable Basic Authentication:</Text>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Flex justifyContent="start" w="70%">
|
<Flex justifyContent="start" w="70%">
|
||||||
<InputField
|
<InputField
|
||||||
|
@ -622,7 +626,7 @@ export default function Environment() {
|
||||||
</Flex>
|
</Flex>
|
||||||
</Stack>
|
</Stack>
|
||||||
<Divider marginTop="2%" marginBottom="2%" />
|
<Divider marginTop="2%" marginBottom="2%" />
|
||||||
<Text fontSize="md" paddingTop="2%">
|
<Text fontSize="md" paddingTop="2%" fontWeight="bold">
|
||||||
Danger
|
Danger
|
||||||
</Text>
|
</Text>
|
||||||
<Stack
|
<Stack
|
||||||
|
@ -633,6 +637,10 @@ export default function Environment() {
|
||||||
borderRadius="5px"
|
borderRadius="5px"
|
||||||
>
|
>
|
||||||
<Stack spacing={6} padding="3% 0">
|
<Stack spacing={6} padding="3% 0">
|
||||||
|
<Text fontStyle="italic" fontSize="sm" color="gray.600">
|
||||||
|
Note: Database related environment variables cannot be updated from
|
||||||
|
dashboard :(
|
||||||
|
</Text>
|
||||||
<Flex>
|
<Flex>
|
||||||
<Flex w="30%" justifyContent="start" alignItems="center">
|
<Flex w="30%" justifyContent="start" alignItems="center">
|
||||||
<Text fontSize="sm">DataBase Name:</Text>
|
<Text fontSize="sm">DataBase Name:</Text>
|
||||||
|
|
|
@ -26,6 +26,7 @@ export const AppRoutes = () => {
|
||||||
<Route path="/" element={<Home />} />
|
<Route path="/" element={<Home />} />
|
||||||
<Route path="users" element={<Users />} />
|
<Route path="users" element={<Users />} />
|
||||||
<Route path="environment" element={<Environment />} />
|
<Route path="environment" element={<Environment />} />
|
||||||
|
<Route path="*" element={<Home />} />
|
||||||
</Route>
|
</Route>
|
||||||
</Routes>
|
</Routes>
|
||||||
</Suspense>
|
</Suspense>
|
||||||
|
@ -35,6 +36,7 @@ export const AppRoutes = () => {
|
||||||
<Suspense fallback={<></>}>
|
<Suspense fallback={<></>}>
|
||||||
<Routes>
|
<Routes>
|
||||||
<Route path="/" element={<Auth />} />
|
<Route path="/" element={<Auth />} />
|
||||||
|
<Route path="*" element={<Auth />} />
|
||||||
</Routes>
|
</Routes>
|
||||||
</Suspense>
|
</Suspense>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,9 +1,3 @@
|
||||||
import {
|
|
||||||
Alert,
|
|
||||||
AlertIcon,
|
|
||||||
AlertTitle,
|
|
||||||
AlertDescription,
|
|
||||||
} from '@chakra-ui/react';
|
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
|
|
||||||
export const hasAdminSecret = () => {
|
export const hasAdminSecret = () => {
|
||||||
|
|
|
@ -22,6 +22,11 @@ type State struct {
|
||||||
// AppHandler is the handler for the /app route
|
// AppHandler is the handler for the /app route
|
||||||
func AppHandler() gin.HandlerFunc {
|
func AppHandler() gin.HandlerFunc {
|
||||||
return func(c *gin.Context) {
|
return func(c *gin.Context) {
|
||||||
|
if envstore.EnvInMemoryStoreObj.GetBoolStoreEnvVariable(constants.EnvKeyDisableLoginPage) {
|
||||||
|
c.JSON(400, gin.H{"error": "login page is not enabled"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
state := c.Query("state")
|
state := c.Query("state")
|
||||||
|
|
||||||
var stateObj State
|
var stateObj State
|
||||||
|
|
|
@ -15,7 +15,6 @@ import (
|
||||||
"github.com/authorizerdev/authorizer/server/graph/model"
|
"github.com/authorizerdev/authorizer/server/graph/model"
|
||||||
"github.com/authorizerdev/authorizer/server/token"
|
"github.com/authorizerdev/authorizer/server/token"
|
||||||
"github.com/authorizerdev/authorizer/server/utils"
|
"github.com/authorizerdev/authorizer/server/utils"
|
||||||
"golang.org/x/crypto/bcrypt"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// UpdateEnvResolver is a resolver for update config mutation
|
// UpdateEnvResolver is a resolver for update config mutation
|
||||||
|
@ -43,6 +42,23 @@ func UpdateEnvResolver(ctx context.Context, params model.UpdateEnvInput) (*model
|
||||||
return res, fmt.Errorf("error un-marshalling params: %t", err)
|
return res, fmt.Errorf("error un-marshalling params: %t", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// in case of admin secret change update the cookie with new hash
|
||||||
|
if params.AdminSecret != nil {
|
||||||
|
if params.OldAdminSecret == nil {
|
||||||
|
return res, errors.New("admin secret and old admin secret are required for secret change")
|
||||||
|
}
|
||||||
|
|
||||||
|
if *params.OldAdminSecret != envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret) {
|
||||||
|
return res, errors.New("old admin secret is not correct")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(*params.AdminSecret) < 6 {
|
||||||
|
err = fmt.Errorf("admin secret must be at least 6 characters")
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
updatedData := envstore.EnvInMemoryStoreObj.GetEnvStoreClone()
|
updatedData := envstore.EnvInMemoryStoreObj.GetEnvStoreClone()
|
||||||
for key, value := range data {
|
for key, value := range data {
|
||||||
if value != nil {
|
if value != nil {
|
||||||
|
@ -106,22 +122,7 @@ func UpdateEnvResolver(ctx context.Context, params model.UpdateEnvInput) (*model
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
encryptedConfig, err := utils.EncryptEnvData(updatedData)
|
|
||||||
if err != nil {
|
|
||||||
return res, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// in case of admin secret change update the cookie with new hash
|
|
||||||
if params.AdminSecret != nil {
|
if params.AdminSecret != nil {
|
||||||
if params.OldAdminSecret == nil {
|
|
||||||
return res, errors.New("admin secret and old admin secret are required for secret change")
|
|
||||||
}
|
|
||||||
|
|
||||||
err := bcrypt.CompareHashAndPassword([]byte(*params.OldAdminSecret), []byte(envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)))
|
|
||||||
if err != nil {
|
|
||||||
return res, errors.New("old admin secret is not correct")
|
|
||||||
}
|
|
||||||
|
|
||||||
hashedKey, err := utils.EncryptPassword(envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret))
|
hashedKey, err := utils.EncryptPassword(envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return res, err
|
return res, err
|
||||||
|
@ -129,6 +130,11 @@ func UpdateEnvResolver(ctx context.Context, params model.UpdateEnvInput) (*model
|
||||||
cookie.SetAdminCookie(gc, hashedKey)
|
cookie.SetAdminCookie(gc, hashedKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
encryptedConfig, err := utils.EncryptEnvData(updatedData)
|
||||||
|
if err != nil {
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
|
||||||
env.EnvData = encryptedConfig
|
env.EnvData = encryptedConfig
|
||||||
_, err = db.Provider.UpdateEnv(env)
|
_, err = db.Provider.UpdateEnv(env)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
package routes
|
package routes
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/authorizerdev/authorizer/server/constants"
|
|
||||||
"github.com/authorizerdev/authorizer/server/envstore"
|
|
||||||
"github.com/authorizerdev/authorizer/server/handlers"
|
"github.com/authorizerdev/authorizer/server/handlers"
|
||||||
"github.com/authorizerdev/authorizer/server/middlewares"
|
"github.com/authorizerdev/authorizer/server/middlewares"
|
||||||
"github.com/gin-contrib/location"
|
"github.com/gin-contrib/location"
|
||||||
|
@ -25,21 +23,19 @@ func InitRouter() *gin.Engine {
|
||||||
|
|
||||||
router.LoadHTMLGlob("templates/*")
|
router.LoadHTMLGlob("templates/*")
|
||||||
// login page app related routes.
|
// login page app related routes.
|
||||||
if !envstore.EnvInMemoryStoreObj.GetBoolStoreEnvVariable(constants.EnvKeyDisableLoginPage) {
|
|
||||||
app := router.Group("/app")
|
app := router.Group("/app")
|
||||||
{
|
{
|
||||||
app.Static("/build", "app/build")
|
app.Static("/build", "app/build")
|
||||||
app.GET("/", handlers.AppHandler())
|
app.GET("/", handlers.AppHandler())
|
||||||
app.GET("/reset-password", handlers.AppHandler())
|
app.GET("/reset-password", handlers.AppHandler())
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// dashboard related routes
|
// dashboard related routes
|
||||||
app := router.Group("/dashboard")
|
dashboard := router.Group("/dashboard")
|
||||||
{
|
{
|
||||||
app.Static("/build", "dashboard/build")
|
dashboard.Static("/build", "dashboard/build")
|
||||||
app.GET("/", handlers.DashboardHandler())
|
dashboard.GET("/", handlers.DashboardHandler())
|
||||||
app.GET("/:page", handlers.DashboardHandler())
|
dashboard.GET("/:page", handlers.DashboardHandler())
|
||||||
}
|
}
|
||||||
return router
|
return router
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user