Common:Utils:OAuth: add scope list component; update interfaces and utils

This commit is contained in:
Timofey Boyko 2023-10-27 11:19:03 +03:00
parent 380bec5048
commit f631a208f7
4 changed files with 270 additions and 112 deletions

View File

@ -0,0 +1,88 @@
import React from "react";
import styled from "styled-components";
//@ts-ignore
import { Base } from "@docspace/components/themes";
import { IFilteredScopes, IScope } from "./interfaces";
import { filterScopeByGroup } from ".";
import { ScopeType } from "./enums";
const StyledScopeList = styled.div`
width: 100%;
display: flex;
flex-direction: column;
gap: 4px;
`;
const StyledScopeItem = styled.div`
width: 100%;
display: flex;
flex-direction: row;
align-items: center;
gap: 8px;
font-size: 13px;
font-weight: 400;
line-height: 20px;
.circle {
width: 4px;
height: 4px;
border-radius: 50%;
background-color: ${(props) => props.theme.mainText};
}
`;
StyledScopeItem.defaultProps = { theme: Base };
interface IScopeListProps {
selectedScopes: string[];
scopes: IScope[];
t: any;
}
const ScopeList = ({ selectedScopes, scopes, t }: IScopeListProps) => {
const [renderedScopes, setRenderedScopes] = React.useState<string[]>([]);
React.useEffect(() => {
const result = [];
const filteredScopes: IFilteredScopes = filterScopeByGroup(
selectedScopes,
scopes
);
for (let key in filteredScopes) {
if (filteredScopes[key].isChecked) {
if (filteredScopes[key].checkedType === ScopeType.read) {
result.push(filteredScopes[key].read.tKey || "");
} else {
result.push(filteredScopes[key].write.tKey || "");
}
}
}
setRenderedScopes([...result]);
}, [selectedScopes, scopes]);
return (
<StyledScopeList className="scope-list">
{renderedScopes.map((scope, index) => (
<StyledScopeItem key={`${scope}-${index}`}>
<div className="circle"></div>
{t(`Common:${scope}`)}
</StyledScopeItem>
))}
</StyledScopeList>
);
};
export default ScopeList;

View File

@ -0,0 +1,11 @@
export const enum ScopeType {
read = "read",
write = "write",
}
export const enum ScopeGroup {
files = "files",
accounts = "accounts",
profiles = "profiles",
rooms = "rooms",
}

View File

@ -1,75 +1,145 @@
import { ClientResDTO, ClientReqDTO, ClientProps } from "./interfaces";
import { ScopeGroup, ScopeType } from "./enums";
import {
IClientResDTO,
IClientReqDTO,
IClientProps,
IScope,
IFilteredScopes,
} from "./interfaces";
export const transformToClientProps = (
clientDto: ClientResDTO
): ClientProps => {
clientDto: IClientResDTO
): IClientProps => {
const {
client_id,
client_secret,
description,
terms_url,
policy_url,
logo_url,
logo,
authentication_method,
redirect_uri,
logout_redirect_uri,
redirect_uris,
logout_redirect_uris,
scopes,
tenant,
invalidated,
name,
enabled,
created_on,
created_by,
modified_by,
modified_on,
website_url,
allowed_origins,
} = clientDto;
const client: ClientProps = {
const client: IClientProps = {
clientId: client_id,
secret: client_secret,
clientSecret: client_secret,
description,
termsUrl: terms_url,
policyUrl: policy_url,
logoUrl: logo_url,
logo,
authenticationMethod: authentication_method,
redirectUri: redirect_uri,
logoutRedirectUri: logout_redirect_uri,
redirectUris: redirect_uris,
logoutRedirectUris: logout_redirect_uris,
scopes,
tenant,
invalidated,
name,
enabled,
createdBy: created_by,
createdOn: created_on,
modifiedBy: modified_by,
modifiedOn: modified_on,
websiteUrl: website_url,
allowedOrigins: allowed_origins,
};
return client;
};
export const transformToClientReqDTO = (
clientProps: ClientProps
): ClientReqDTO => {
clientProps: IClientProps
): IClientReqDTO => {
const {
name,
description,
termsUrl: terms_url,
policyUrl: policy_url,
logoUrl: logo_url,
logo,
authenticationMethod,
redirectUri: redirect_uri,
logoutRedirectUri: logout_redirect_uri,
redirectUris: redirect_uris,
logoutRedirectUris: logout_redirect_uris,
scopes,
tenant,
websiteUrl,
allowedOrigins,
} = clientProps;
const client: ClientReqDTO = {
const client: IClientReqDTO = {
name,
description,
logo_url,
redirect_uri,
logout_redirect_uri,
logo,
redirect_uris,
logout_redirect_uris,
terms_url,
policy_url,
scopes,
tenant,
authentication_method: authenticationMethod,
website_url: websiteUrl,
allowed_origins: allowedOrigins,
};
return client;
};
export const getScopeTKeyDescription = (group: ScopeGroup, type: ScopeType) => {
const tKey = `OAuth${group.replace(
/^./,
group[0].toUpperCase()
)}${type.replace(/^./, type[0].toUpperCase())}Description`;
return tKey;
};
export const filterScopeByGroup = (
checkedScopes: string[],
scopes: IScope[]
) => {
const filteredScopes: IFilteredScopes = {};
scopes.forEach((scope) => {
const isChecked = checkedScopes.includes(scope.name);
const isRead = ScopeType.read === scope.type;
const tKey = getScopeTKeyDescription(scope.group, scope.type);
const read = isRead ? { ...scope, tKey } : ({} as IScope);
const write = !isRead ? { ...scope, tKey } : ({} as IScope);
if (filteredScopes[scope.group]) {
if (isRead) {
filteredScopes[scope.group].read = read;
if (!filteredScopes[scope.group].isChecked && isChecked) {
filteredScopes[scope.group].isChecked = isChecked;
filteredScopes[scope.group].checkedType = ScopeType.read;
}
} else {
filteredScopes[scope.group].write = write;
if (isChecked) {
filteredScopes[scope.group].isChecked = isChecked;
filteredScopes[scope.group].checkedType = ScopeType.write;
}
}
} else {
filteredScopes[scope.group] = {
isChecked,
checkedType: isChecked ? scope.type : undefined,
read,
write,
};
}
});
return filteredScopes;
};

View File

@ -1,57 +1,80 @@
export type Scope = {
name: string;
description: string;
};
import { ScopeGroup, ScopeType } from "./enums";
export interface ClientProps {
export interface IScope {
name: string;
group: ScopeGroup;
type: ScopeType;
tKey?: string;
}
export interface IFilteredScopes {
[key: string]: {
isChecked: boolean;
checkedType?: ScopeType;
read: IScope;
write: IScope;
};
}
export interface INoAuthClientProps {
name: string;
logo: string;
websiteUrl: string;
policyUrl?: string;
termsUrl?: string;
scopes?: string[];
}
export interface IClientProps {
name: string;
clientId: string;
secret: string;
name: string;
clientSecret: string;
description: string;
logoUrl?: string;
redirectUri: string;
policyUrl: string;
termsUrl: string;
logoutRedirectUri: string;
logo: string;
authenticationMethod: string;
scopes: string[];
enabled: boolean;
tenant: number;
invalidated?: boolean;
redirectUris: string[];
logoutRedirectUris: string[];
enabled: boolean;
invalidated: boolean;
scopes: string[];
createdOn: Date;
modifiedOn: Date;
createdBy: string;
modifiedBy: string;
websiteUrl: string;
allowedOrigins: string[];
}
export interface ClientReqDTO {
export interface IClientReqDTO {
name: string;
description: string;
logo_url?: string;
redirect_uri: string;
policy_url: string;
logo: string;
authentication_method: string;
terms_url: string;
logout_redirect_uri: string;
policy_url: string;
redirect_uris: string[];
logout_redirect_uris: string[];
scopes: string[];
tenant: number;
website_url: string;
allowed_origins: string[];
}
export interface ClientResDTO {
export interface IClientResDTO {
name: string;
client_id: string;
client_secret: string;
name: string;
description: string;
logo_url?: string;
logo: string;
redirect_uri: string;
redirect_uris: string[];
terms_url: string;
policy_url: string;
logout_redirect_uri: string;
logout_redirect_uris: string[];
authentication_method: string;
@ -59,63 +82,29 @@ export interface ClientResDTO {
enabled: boolean;
tenant: number;
invalidated?: boolean;
invalidated: boolean;
created_on: Date;
modified_on: Date;
created_by: string;
modified_by: string;
website_url: string;
allowed_origins: string[];
}
export interface ClientListProps {
content: ClientProps[];
empty: boolean;
first: boolean;
last: true;
number: number;
numberOfElements: number;
pageable: {
offset: number;
pageNumber: number;
pageSize: number;
paged: boolean;
sort: {
empty: boolean;
sorted: boolean;
unsorted: boolean;
};
unpaged: boolean;
};
size: number;
sort: {
empty: boolean;
sorted: boolean;
unsorted: boolean;
};
totalElements: number;
totalPages: number;
export interface IClientListProps {
content: IClientProps[];
page: number;
limit: number;
}
export type ClientListDTO = {
content: ClientResDTO[];
empty: boolean;
first: boolean;
last: true;
number: number;
numberOfElements: number;
pageable: {
offset: number;
pageNumber: number;
pageSize: number;
paged: boolean;
sort: {
empty: boolean;
sorted: boolean;
unsorted: boolean;
};
unpaged: boolean;
};
size: number;
sort: {
empty: boolean;
sorted: boolean;
unsorted: boolean;
};
totalElements: number;
totalPages: number;
};
export interface IClientListDTO {
data: IClientResDTO[];
page: number;
limit: number;
}
export interface ISubmitReqDTO {
client_id: string;
state: string;
scopes: string[];
}