Skip to content

Commit 32fb954

Browse files
authored
Merge pull request #281 from authorizerdev/development
chore: 1.1.22-rc.0
2 parents 6e09307 + 65eadb6 commit 32fb954

File tree

18 files changed

+272
-36
lines changed

18 files changed

+272
-36
lines changed

app/src/pages/login.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,12 @@ export default function Login({ urlProps }: { urlProps: Record<string, any> }) {
6060
{view === VIEW_TYPES.FORGOT_PASSWORD && (
6161
<Fragment>
6262
<h1 style={{ textAlign: 'center' }}>Forgot Password</h1>
63-
<AuthorizerForgotPassword urlProps={urlProps} />
63+
<AuthorizerForgotPassword
64+
urlProps={{
65+
...urlProps,
66+
redirect_uri: `${window.location.origin}/app/reset-password`,
67+
}}
68+
/>
6469
<Footer>
6570
<Link
6671
to="#"

dashboard/src/components/EditUserModal.tsx

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React from 'react';
1+
import React, { useState } from 'react';
22
import {
33
Button,
44
Center,
@@ -20,13 +20,14 @@ import { useClient } from 'urql';
2020
import { FaSave } from 'react-icons/fa';
2121
import InputField from './InputField';
2222
import {
23-
ArrayInputType,
2423
DateInputType,
24+
MultiSelectInputType,
2525
SelectInputType,
2626
TextInputType,
2727
} from '../constants';
2828
import { getObjectDiff } from '../utils';
2929
import { UpdateUser } from '../graphql/mutation';
30+
import { GetAvailableRolesQuery } from '../graphql/queries';
3031

3132
const GenderTypes = {
3233
Undisclosed: null,
@@ -57,8 +58,9 @@ const EditUserModal = ({
5758
}) => {
5859
const client = useClient();
5960
const toast = useToast();
61+
const [availableRoles, setAvailableRoles] = useState<string[]>([]);
6062
const { isOpen, onOpen, onClose } = useDisclosure();
61-
const [userData, setUserData] = React.useState<userDataTypes>({
63+
const [userData, setUserData] = useState<userDataTypes>({
6264
id: '',
6365
email: '',
6466
given_name: '',
@@ -73,7 +75,17 @@ const EditUserModal = ({
7375
});
7476
React.useEffect(() => {
7577
setUserData(user);
78+
fetchAvailableRoles();
7679
}, []);
80+
const fetchAvailableRoles = async () => {
81+
const res = await client.query(GetAvailableRolesQuery).toPromise();
82+
if (res.data?._env?.ROLES && res.data?._env?.PROTECTED_ROLES) {
83+
setAvailableRoles([
84+
...res.data._env.ROLES,
85+
...res.data._env.PROTECTED_ROLES,
86+
]);
87+
}
88+
};
7789
const saveHandler = async () => {
7890
const diff = getObjectDiff(user, userData);
7991
const updatedUserData = diff.reduce(
@@ -221,7 +233,8 @@ const EditUserModal = ({
221233
<InputField
222234
variables={userData}
223235
setVariables={setUserData}
224-
inputType={ArrayInputType.USER_ROLES}
236+
availableRoles={availableRoles}
237+
inputType={MultiSelectInputType.USER_ROLES}
225238
/>
226239
</Center>
227240
</Flex>

dashboard/src/components/EnvComponents/EmailConfiguration.tsx

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,26 @@ const EmailConfigurations = ({
4848
/>
4949
</Center>
5050
</Flex>
51+
<Flex direction={isNotSmallerScreen ? 'row' : 'column'}>
52+
<Flex
53+
w={isNotSmallerScreen ? '30%' : '40%'}
54+
justifyContent="start"
55+
alignItems="center"
56+
>
57+
<Text fontSize="sm">SMTP Local Name:</Text>
58+
</Flex>
59+
<Center
60+
w={isNotSmallerScreen ? '70%' : '100%'}
61+
mt={isNotSmallerScreen ? '0' : '3'}
62+
>
63+
<InputField
64+
borderRadius={5}
65+
variables={variables}
66+
setVariables={setVariables}
67+
inputType={TextInputType.SMTP_LOCAL_NAME}
68+
/>
69+
</Center>
70+
</Flex>
5171
<Flex direction={isNotSmallerScreen ? 'row' : 'column'}>
5272
<Flex
5373
w={isNotSmallerScreen ? '30%' : '40%'}

dashboard/src/components/InputField.tsx

Lines changed: 97 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React from 'react';
1+
import React, { useState } from 'react';
22
import {
33
Box,
44
Flex,
@@ -13,13 +13,20 @@ import {
1313
Textarea,
1414
Switch,
1515
Text,
16+
MenuButton,
17+
MenuList,
18+
MenuItemOption,
19+
MenuOptionGroup,
20+
Button,
21+
Menu,
1622
} from '@chakra-ui/react';
1723
import {
1824
FaRegClone,
1925
FaRegEye,
2026
FaRegEyeSlash,
2127
FaPlus,
2228
FaTimes,
29+
FaAngleDown,
2330
} from 'react-icons/fa';
2431
import {
2532
ArrayInputOperations,
@@ -30,6 +37,7 @@ import {
3037
TextAreaInputType,
3138
SwitchInputType,
3239
DateInputType,
40+
MultiSelectInputType,
3341
} from '../constants';
3442
import { copyTextToClipboard } from '../utils';
3543

@@ -39,13 +47,16 @@ const InputField = ({
3947
setVariables,
4048
fieldVisibility,
4149
setFieldVisibility,
50+
availableRoles,
4251
...downshiftProps
4352
}: any) => {
4453
const props = {
4554
size: 'sm',
4655
...downshiftProps,
4756
};
48-
const [inputFieldVisibility, setInputFieldVisibility] = React.useState<
57+
const [availableUserRoles, setAvailableUserRoles] =
58+
useState<string[]>(availableRoles);
59+
const [inputFieldVisibility, setInputFieldVisibility] = useState<
4960
Record<string, boolean>
5061
>({
5162
ROLES: false,
@@ -54,7 +65,7 @@ const InputField = ({
5465
ALLOWED_ORIGINS: false,
5566
roles: false,
5667
});
57-
const [inputData, setInputData] = React.useState<Record<string, string>>({
68+
const [inputData, setInputData] = useState<Record<string, string>>({
5869
ROLES: '',
5970
DEFAULT_ROLES: '',
6071
PROTECTED_ROLES: '',
@@ -116,7 +127,7 @@ const InputField = ({
116127
<InputGroup size="sm">
117128
<Input
118129
{...props}
119-
value={variables[inputType] ?? ''}
130+
value={variables[inputType] || ''}
120131
onChange={(
121132
event: Event & {
122133
target: HTMLInputElement;
@@ -221,7 +232,7 @@ const InputField = ({
221232
size="xs"
222233
minW="150px"
223234
placeholder="add a new value"
224-
value={inputData[inputType] ?? ''}
235+
value={inputData[inputType] || ''}
225236
onChange={(e: any) => {
226237
setInputData({ ...inputData, [inputType]: e.target.value });
227238
}}
@@ -278,6 +289,87 @@ const InputField = ({
278289
</Select>
279290
);
280291
}
292+
if (Object.values(MultiSelectInputType).includes(inputType)) {
293+
return (
294+
<Flex w="100%" style={{ position: 'relative' }}>
295+
<Flex
296+
border="1px solid #e2e8f0"
297+
w="100%"
298+
borderRadius="var(--chakra-radii-sm)"
299+
p="1% 0 0 2.5%"
300+
overflowX={variables[inputType].length > 3 ? 'scroll' : 'hidden'}
301+
overflowY="hidden"
302+
justifyContent="space-between"
303+
alignItems="center"
304+
>
305+
<Flex justifyContent="start" alignItems="center" w="100%" wrap="wrap">
306+
{variables[inputType].map((role: string, index: number) => (
307+
<Box key={index} margin="0.5%" role="group">
308+
<Tag
309+
size="sm"
310+
variant="outline"
311+
colorScheme="gray"
312+
minW="fit-content"
313+
>
314+
<TagLabel cursor="default">{role}</TagLabel>
315+
<TagRightIcon
316+
boxSize="12px"
317+
as={FaTimes}
318+
display="none"
319+
cursor="pointer"
320+
_groupHover={{ display: 'block' }}
321+
onClick={() =>
322+
updateInputHandler(
323+
inputType,
324+
ArrayInputOperations.REMOVE,
325+
role,
326+
)
327+
}
328+
/>
329+
</Tag>
330+
</Box>
331+
))}
332+
</Flex>
333+
<Menu matchWidth={true}>
334+
<MenuButton px="10px" py="7.5px">
335+
<FaAngleDown />
336+
</MenuButton>
337+
<MenuList
338+
position="absolute"
339+
top="0"
340+
right="0"
341+
zIndex="10"
342+
maxH="150"
343+
overflowX="scroll"
344+
>
345+
<MenuOptionGroup
346+
title={undefined}
347+
value={variables[inputType]}
348+
type="checkbox"
349+
onChange={(values: string[] | string) => {
350+
setVariables({
351+
...variables,
352+
[inputType]: values,
353+
});
354+
}}
355+
>
356+
{availableUserRoles.map((role) => {
357+
return (
358+
<MenuItemOption
359+
key={`multiselect-menu-${role}`}
360+
value={role}
361+
>
362+
{role}
363+
</MenuItemOption>
364+
);
365+
})}
366+
</MenuOptionGroup>
367+
</MenuList>
368+
</Menu>
369+
</Flex>
370+
</Flex>
371+
);
372+
}
281373
if (Object.values(TextAreaInputType).includes(inputType)) {
282374
return (
283375
<Textarea

dashboard/src/constants.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ export const TextInputType = {
1515
SMTP_HOST: 'SMTP_HOST',
1616
SMTP_PORT: 'SMTP_PORT',
1717
SMTP_USERNAME: 'SMTP_USERNAME',
18+
SMTP_LOCAL_NAME: 'SMTP_LOCAL_NAME',
1819
SENDER_EMAIL: 'SENDER_EMAIL',
1920
ORGANIZATION_NAME: 'ORGANIZATION_NAME',
2021
ORGANIZATION_LOGO: 'ORGANIZATION_LOGO',
@@ -48,14 +49,17 @@ export const ArrayInputType = {
4849
DEFAULT_ROLES: 'DEFAULT_ROLES',
4950
PROTECTED_ROLES: 'PROTECTED_ROLES',
5051
ALLOWED_ORIGINS: 'ALLOWED_ORIGINS',
51-
USER_ROLES: 'roles',
5252
};
5353

5454
export const SelectInputType = {
5555
JWT_TYPE: 'JWT_TYPE',
5656
GENDER: 'gender',
5757
};
5858

59+
export const MultiSelectInputType = {
60+
USER_ROLES: 'roles',
61+
};
62+
5963
export const TextAreaInputType = {
6064
CUSTOM_ACCESS_TOKEN_SCRIPT: 'CUSTOM_ACCESS_TOKEN_SCRIPT',
6165
JWT_PRIVATE_KEY: 'JWT_PRIVATE_KEY',
@@ -129,6 +133,7 @@ export interface envVarTypes {
129133
SMTP_PORT: string;
130134
SMTP_USERNAME: string;
131135
SMTP_PASSWORD: string;
136+
SMTP_LOCAL_NAME: string;
132137
SENDER_EMAIL: string;
133138
ALLOWED_ORIGINS: [string] | [];
134139
ORGANIZATION_NAME: string;

dashboard/src/graphql/queries/index.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ export const EnvVariablesQuery = `
4545
SMTP_PORT
4646
SMTP_USERNAME
4747
SMTP_PASSWORD
48+
SMTP_LOCAL_NAME
4849
SENDER_EMAIL
4950
ALLOWED_ORIGINS
5051
ORGANIZATION_NAME
@@ -169,3 +170,12 @@ export const WebhookLogsQuery = `
169170
}
170171
}
171172
`;
173+
174+
export const GetAvailableRolesQuery = `
175+
query {
176+
_env {
177+
ROLES
178+
PROTECTED_ROLES
179+
}
180+
}
181+
`;

dashboard/src/pages/Environment.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ const Environment = () => {
6565
SMTP_PORT: '',
6666
SMTP_USERNAME: '',
6767
SMTP_PASSWORD: '',
68+
SMTP_LOCAL_NAME: '',
6869
SENDER_EMAIL: '',
6970
ALLOWED_ORIGINS: [],
7071
ORGANIZATION_NAME: '',

server/constants/env.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ const (
5151
EnvKeySmtpUsername = "SMTP_USERNAME"
5252
// EnvKeySmtpPassword key for env variable SMTP_PASSWORD
5353
EnvKeySmtpPassword = "SMTP_PASSWORD"
54+
// EnvKeySmtpLocalName key for env variable SMTP_LOCAL_NAME
55+
EnvKeySmtpLocalName = "SMTP_LOCAL_NAME"
5456
// EnvKeySenderEmail key for env variable SENDER_EMAIL
5557
EnvKeySenderEmail = "SENDER_EMAIL"
5658
// EnvKeyIsEmailServiceEnabled key for env variable IS_EMAIL_SERVICE_ENABLED

server/email/email.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"context"
66
"crypto/tls"
77
"strconv"
8+
"strings"
89
"text/template"
910

1011
log "github.com/sirupsen/logrus"
@@ -126,6 +127,12 @@ func SendEmail(to []string, event string, data map[string]interface{}) error {
126127
return err
127128
}
128129

130+
smtpLocalName, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeySmtpLocalName)
131+
if err != nil {
132+
log.Debugf("Error while getting smtp localname from env variable: %v", err)
133+
smtpLocalName = ""
134+
}
135+
129136
isProd, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyIsProd)
130137
if err != nil {
131138
log.Errorf("Error while getting env variable: %v", err)
@@ -141,6 +148,11 @@ func SendEmail(to []string, event string, data map[string]interface{}) error {
141148
if !isProd {
142149
d.TLSConfig = &tls.Config{InsecureSkipVerify: true}
143150
}
151+
152+
if strings.TrimSpace(smtpLocalName) != "" {
153+
d.LocalName = smtpLocalName
154+
}
155+
144156
if err := d.DialAndSend(m); err != nil {
145157
log.Debug("SMTP Failed: ", err)
146158
return err

server/env/env.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ func InitAllEnv() error {
5555
osSmtpPort := os.Getenv(constants.EnvKeySmtpPort)
5656
osSmtpUsername := os.Getenv(constants.EnvKeySmtpUsername)
5757
osSmtpPassword := os.Getenv(constants.EnvKeySmtpPassword)
58+
osSmtpLocalName := os.Getenv(constants.EnvKeySmtpLocalName)
5859
osSenderEmail := os.Getenv(constants.EnvKeySenderEmail)
5960
osJwtType := os.Getenv(constants.EnvKeyJwtType)
6061
osJwtSecret := os.Getenv(constants.EnvKeyJwtSecret)
@@ -205,6 +206,13 @@ func InitAllEnv() error {
205206
envData[constants.EnvKeySmtpUsername] = osSmtpUsername
206207
}
207208

209+
if val, ok := envData[constants.EnvKeySmtpLocalName]; !ok || val == "" {
210+
envData[constants.EnvKeySmtpLocalName] = osSmtpLocalName
211+
}
212+
if osSmtpLocalName != "" && envData[constants.EnvKeySmtpLocalName] != osSmtpLocalName {
213+
envData[constants.EnvKeySmtpLocalName] = osSmtpLocalName
214+
}
215+
208216
if val, ok := envData[constants.EnvKeySmtpPassword]; !ok || val == "" {
209217
envData[constants.EnvKeySmtpPassword] = osSmtpPassword
210218
}

0 commit comments

Comments
 (0)