From c6503aaeb9f34cab00f2325e4842faea2328b98d Mon Sep 17 00:00:00 2001 From: Movin Silva Date: Mon, 6 May 2024 16:33:55 +0530 Subject: [PATCH 01/16] feat(core): :sparkles: add logout & downgrade ts version downgrade ts version to get the support for eslint --- packages/core/package.json | 2 +- packages/core/src/api/logout.ts | 66 +++++++++++++++++++++++++++++++++ pnpm-lock.yaml | 2 +- 3 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 packages/core/src/api/logout.ts diff --git a/packages/core/package.json b/packages/core/package.json index 9ee83335..3a3e11b2 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -44,7 +44,7 @@ "prettier": "^3.2.5", "rollup-plugin-dts": "^6.1.0", "tslib": "^2.6.2", - "typescript": "^5.4.5" + "typescript": "^5.1.6" }, "publishConfig": { "access": "public" diff --git a/packages/core/src/api/logout.ts b/packages/core/src/api/logout.ts new file mode 100644 index 00000000..f1ae730a --- /dev/null +++ b/packages/core/src/api/logout.ts @@ -0,0 +1,66 @@ +/** + * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {AuthClient, ResponseMode} from 'src/auth-client'; +import AsgardeoUIException from 'src/exception'; + +const logout = async (): Promise => { + let response: Response; + let logoutUrl: string; + + const headers: Headers = new Headers(); + headers.append('Accept', 'application/json'); + headers.append('Content-Type', 'application/x-www-form-urlencoded'); + + const formBody: URLSearchParams = new URLSearchParams(); + + try { + formBody.append('id_token_hint', await AuthClient.getInstance().getIDToken()); + formBody.append('client_id', (await AuthClient.getInstance().getDataLayer().getConfigData()).clientID); + formBody.append('response_mode', ResponseMode.direct); + } catch (error) { + throw new AsgardeoUIException('JS_UI_CORE-LOGOUT-L-IV', 'Failed to build the body of the logout request.'); + } + + const requestOptions: RequestInit = { + body: formBody.toString(), + headers, + method: 'POST', + }; + + try { + logoutUrl = (await AuthClient.getInstance().getOIDCServiceEndpoints()).endSessionEndpoint; + } catch (error) { + throw new AsgardeoUIException('JS_UI_CORE-LOGOUT-L-NF', 'Failed to retrieve the logout endpoint.'); + } + + try { + response = await fetch(logoutUrl, requestOptions); + } catch (error) { + throw new AsgardeoUIException('JS_UI_CORE-LOGOUT-L-NE', 'Failed to send a request to the logout endpoint.'); + } + + if (!response.ok) { + throw new AsgardeoUIException( + 'JS_UI_CORE-LOGOUT-L-HE', + 'Failed to receive a successful response from the logout endpoint.', + ); + } +}; + +export default logout; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7f156731..e39731a9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -61,7 +61,7 @@ importers: specifier: ^2.6.2 version: 2.6.2 typescript: - specifier: ^5.4.5 + specifier: ^5.1.6 version: 5.4.5 packages/react: From 353b2efd09604cc8e380e2366f5ee1a5bbef564a Mon Sep 17 00:00:00 2001 From: Movin Silva Date: Mon, 6 May 2024 16:38:12 +0530 Subject: [PATCH 02/16] refactor(core): :recycle: rename branding-preference-text file to get-branding-preference-text --- ...ing-preference-text.ts => get-branding-preference-text.ts} | 0 packages/core/src/api/public-api.ts | 2 +- packages/core/src/i18n/i18n.ts | 4 ++-- 3 files changed, 3 insertions(+), 3 deletions(-) rename packages/core/src/api/{branding-preference-text.ts => get-branding-preference-text.ts} (100%) diff --git a/packages/core/src/api/branding-preference-text.ts b/packages/core/src/api/get-branding-preference-text.ts similarity index 100% rename from packages/core/src/api/branding-preference-text.ts rename to packages/core/src/api/get-branding-preference-text.ts diff --git a/packages/core/src/api/public-api.ts b/packages/core/src/api/public-api.ts index f87cf4a4..88bb7f4c 100644 --- a/packages/core/src/api/public-api.ts +++ b/packages/core/src/api/public-api.ts @@ -20,4 +20,4 @@ export {default as authorize} from './authorize'; export {default as authenticate} from './authenticate'; export {default as getBrandingPreference} from './branding-preference'; export {default as getProfileInformation} from './profile'; -export {default as getBrandingPreferenceText} from './branding-preference-text'; +export {default as getBrandingPreferenceText} from './get-branding-preference-text'; diff --git a/packages/core/src/i18n/i18n.ts b/packages/core/src/i18n/i18n.ts index 1efafafb..934eb612 100644 --- a/packages/core/src/i18n/i18n.ts +++ b/packages/core/src/i18n/i18n.ts @@ -17,10 +17,10 @@ */ import merge from 'lodash.merge'; -import getBrandingPreferenceText from '../api/branding-preference-text'; +import {GetLocalization, TextObject} from './screens/model'; +import getBrandingPreferenceText from '../api/get-branding-preference-text'; import {AuthClient} from '../auth-client'; import {BrandingPreferenceTextAPIResponse} from '../models/branding-text-api-response'; -import {GetLocalization, TextObject} from './screens/model'; /** * Fetch and merge branding properties. From 00ddb20e69059c569ef09123f294d39c96e648b3 Mon Sep 17 00:00:00 2001 From: Movin Silva Date: Mon, 6 May 2024 16:39:21 +0530 Subject: [PATCH 03/16] refactor(core): :recycle: rename branding-preference file to get-branding-preference --- .../api/{branding-preference.ts => get-branding-preference.ts} | 0 packages/core/src/api/public-api.ts | 2 +- packages/core/src/branding/branding.ts | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename packages/core/src/api/{branding-preference.ts => get-branding-preference.ts} (100%) diff --git a/packages/core/src/api/branding-preference.ts b/packages/core/src/api/get-branding-preference.ts similarity index 100% rename from packages/core/src/api/branding-preference.ts rename to packages/core/src/api/get-branding-preference.ts diff --git a/packages/core/src/api/public-api.ts b/packages/core/src/api/public-api.ts index 88bb7f4c..7f36c4b1 100644 --- a/packages/core/src/api/public-api.ts +++ b/packages/core/src/api/public-api.ts @@ -18,6 +18,6 @@ export {default as authorize} from './authorize'; export {default as authenticate} from './authenticate'; -export {default as getBrandingPreference} from './branding-preference'; +export {default as getBrandingPreference} from './get-branding-preference'; export {default as getProfileInformation} from './profile'; export {default as getBrandingPreferenceText} from './get-branding-preference-text'; diff --git a/packages/core/src/branding/branding.ts b/packages/core/src/branding/branding.ts index 60e224ec..c9516de2 100644 --- a/packages/core/src/branding/branding.ts +++ b/packages/core/src/branding/branding.ts @@ -18,7 +18,7 @@ import merge from 'lodash.merge'; import DEFAULT_BRANDING from './default-branding/default-branding'; -import getBrandingPreference from '../api/branding-preference'; +import getBrandingPreference from '../api/get-branding-preference'; import {AuthClient} from '../auth-client'; import {BrandingPreferenceAPIResponseInterface} from '../models/branding-api-response'; import {Customization, GetBranding} from '../models/customization'; From 1f4b061524756e4c85c7d7c30a6816555c875077 Mon Sep 17 00:00:00 2001 From: Movin Silva Date: Mon, 6 May 2024 16:41:36 +0530 Subject: [PATCH 04/16] refactor(core): :recycle: rename profile file to get-profile-information --- .../core/src/api/{profile.ts => get-profile-information.ts} | 0 packages/core/src/api/public-api.ts | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename packages/core/src/api/{profile.ts => get-profile-information.ts} (100%) diff --git a/packages/core/src/api/profile.ts b/packages/core/src/api/get-profile-information.ts similarity index 100% rename from packages/core/src/api/profile.ts rename to packages/core/src/api/get-profile-information.ts diff --git a/packages/core/src/api/public-api.ts b/packages/core/src/api/public-api.ts index 7f36c4b1..2e22aef2 100644 --- a/packages/core/src/api/public-api.ts +++ b/packages/core/src/api/public-api.ts @@ -19,5 +19,5 @@ export {default as authorize} from './authorize'; export {default as authenticate} from './authenticate'; export {default as getBrandingPreference} from './get-branding-preference'; -export {default as getProfileInformation} from './profile'; +export {default as getProfileInformation} from './get-profile-information'; export {default as getBrandingPreferenceText} from './get-branding-preference-text'; From ee1212bdf554e03af3418e2445a82b73677c240b Mon Sep 17 00:00:00 2001 From: Movin Silva Date: Mon, 6 May 2024 17:35:04 +0530 Subject: [PATCH 05/16] refactor(core): :recycle: rename branding file to get-branding --- packages/core/src/branding/{branding.ts => get-branding.ts} | 0 packages/core/src/index.ts | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename packages/core/src/branding/{branding.ts => get-branding.ts} (100%) diff --git a/packages/core/src/branding/branding.ts b/packages/core/src/branding/get-branding.ts similarity index 100% rename from packages/core/src/branding/branding.ts rename to packages/core/src/branding/get-branding.ts diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 2b65a8a7..86e2088b 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -17,7 +17,7 @@ */ export * from './api/public-api'; -export {default as getBranding} from './branding/branding'; +export {default as getBranding} from './branding/get-branding'; export * from './i18n/public'; export * from './auth-client'; export * from './models/public-models'; From ade9935ca11a7a8af0b4759e60cdbe50c81962af Mon Sep 17 00:00:00 2001 From: Movin Silva Date: Mon, 6 May 2024 17:41:49 +0530 Subject: [PATCH 06/16] refactor(core): :recycle: rename i18n file to get-localization --- packages/core/src/i18n/{i18n.ts => get-localization.ts} | 0 packages/core/src/i18n/public.ts | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename packages/core/src/i18n/{i18n.ts => get-localization.ts} (100%) diff --git a/packages/core/src/i18n/i18n.ts b/packages/core/src/i18n/get-localization.ts similarity index 100% rename from packages/core/src/i18n/i18n.ts rename to packages/core/src/i18n/get-localization.ts diff --git a/packages/core/src/i18n/public.ts b/packages/core/src/i18n/public.ts index 34ffb7ba..a8c9cec7 100644 --- a/packages/core/src/i18n/public.ts +++ b/packages/core/src/i18n/public.ts @@ -18,4 +18,4 @@ export * from './screens/model'; export * from './screens/keys'; -export {default as getLocalization} from './i18n'; +export {default as getLocalization} from './get-localization'; From a5742cce3947dfbc785ad48d2e565382c45913df Mon Sep 17 00:00:00 2001 From: Movin Silva Date: Mon, 6 May 2024 18:14:02 +0530 Subject: [PATCH 07/16] feat(core): :sparkles: add isEmpty function --- packages/core/src/utils/is-empty.ts | 55 +++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 packages/core/src/utils/is-empty.ts diff --git a/packages/core/src/utils/is-empty.ts b/packages/core/src/utils/is-empty.ts new file mode 100644 index 00000000..d7922785 --- /dev/null +++ b/packages/core/src/utils/is-empty.ts @@ -0,0 +1,55 @@ +/** + * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * Checks if the given value is empty. + * + * @param {unknown} value - The value to check. + * @returns {boolean} Returns `true` if the value is empty, otherwise `false`. + * + * @example + * isEmpty(null); // => true + * isEmpty(''); // => true + * isEmpty([]); // => true + * isEmpty({}); // => true + * isEmpty('Hello'); // => false + * isEmpty([1, 2, 3]); // => false + * isEmpty({ a: 1 }); // => false + */ +const isEmpty = (value: unknown): boolean => { + /** + * If the value is null or undefined, return true. + */ + if (value === null || undefined) { + return true; + } + + /** + * If the value is a string or an array, check if it's length is 0. If it is, return true. + */ + if (typeof value === 'string' || Array.isArray(value)) { + return value.length === 0; + } + + /** + * If the value is an object, check if it has any keys. If it doesn't, return true. + */ + return Object.keys(value).length === 0; +}; + +export default isEmpty; From 6a0c42555e318bb14259aa2abc5494831f947b34 Mon Sep 17 00:00:00 2001 From: Movin Silva Date: Mon, 6 May 2024 18:15:37 +0530 Subject: [PATCH 08/16] feat(core): :sparkles: add get branding css function --- .../core/src/branding/get-branding-css.ts | 119 ++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 packages/core/src/branding/get-branding-css.ts diff --git a/packages/core/src/branding/get-branding-css.ts b/packages/core/src/branding/get-branding-css.ts new file mode 100644 index 00000000..bc85214b --- /dev/null +++ b/packages/core/src/branding/get-branding-css.ts @@ -0,0 +1,119 @@ +/** + * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {BrandingPreferenceThemeInterface} from '../models/branding-api-response'; +import isEmpty from '../utils/is-empty'; + +const getBrandingCSS = (theme: BrandingPreferenceThemeInterface): string => { + if (!theme) { + return ''; + } + + const footerFontColor: string = !isEmpty(theme[theme.activeTheme].footer.font.color) + ? theme[theme.activeTheme].footer.font.color + : 'inherit'; + const headingFontColor: string = !isEmpty(theme[theme.activeTheme].typography.heading.font.color) + ? theme[theme.activeTheme].typography.heading.font.color + : 'inherit'; + const loginBoxFontColor: string = !isEmpty(theme[theme.activeTheme].loginBox.font.color) + ? theme[theme.activeTheme].loginBox.font.color + : 'inherit'; + const inputBaseFontColor: string = !isEmpty(theme[theme.activeTheme].inputs.base.font.color) + ? theme[theme.activeTheme].inputs.base.font.color + : 'inherit'; + const inputBaseLabelFontColor: string = !isEmpty(theme[theme.activeTheme].inputs.base.labels.font.color) + ? theme[theme.activeTheme].inputs.base.labels.font.color + : 'inherit'; + + return ` + ${ + theme[theme.activeTheme].typography.font.importURL + ? `@import url(${theme[theme.activeTheme].typography.font.importURL});` + : '' + } + + :root { + --asg-colors-primary-main: ${theme[theme.activeTheme].colors.primary.main}; + --asg-colors-secondary-main: ${theme[theme.activeTheme].colors.secondary.main}; + --asg-colors-background-body-main: ${theme[theme.activeTheme].colors.background?.body?.main}; + --asg-colors-background-surface-main: ${theme[theme.activeTheme].colors.background?.surface?.main}; + --asg-colors-background-surface-light: ${theme[theme.activeTheme].colors.background?.surface?.light}; + --asg-colors-background-surface-dark: ${theme[theme.activeTheme].colors.background?.surface?.dark}; + --asg-colors-background-surface-inverted: ${theme[theme.activeTheme].colors.background?.surface?.inverted}; + --asg-colors-outlined-default: ${theme[theme.activeTheme].colors.outlined?.default}; + --asg-colors-text-primary: ${theme[theme.activeTheme].colors.text?.primary}; + --asg-colors-text-secondary: ${theme[theme.activeTheme].colors.text?.secondary}; + --asg-colors-alerts-error-main: ${theme[theme.activeTheme].colors.alerts?.error?.main}; + --asg-colors-alerts-neutral-main: ${theme[theme.activeTheme].colors.alerts?.neutral?.main}; + --asg-colors-alerts-info-main: ${theme[theme.activeTheme].colors.alerts?.info?.main}; + --asg-colors-alerts-warning-main: ${theme[theme.activeTheme].colors.alerts?.warning?.main}; + --asg-colors-illustrations-primary-main: ${theme[theme.activeTheme].colors.illustrations?.primary?.main}; + --asg-colors-illustrations-secondary-main: ${theme[theme.activeTheme].colors.illustrations?.secondary?.main}; + --asg-colors-illustrations-accent1-main: ${theme[theme.activeTheme].colors.illustrations?.accent1?.main}; + --asg-colors-illustrations-accent2-main: ${theme[theme.activeTheme].colors.illustrations?.accent2?.main}; + --asg-colors-illustrations-accent3-main: ${theme[theme.activeTheme].colors.illustrations?.accent3?.main}; + + /* Components */ + --asg-footer-text-color: ${footerFontColor}; + --asg-footer-border-color: ${ + theme[theme.activeTheme].footer?.border?.borderColor || 'var(--asg-colors-outlined-default)' + }; + --asg-primary-font-family: ${theme[theme.activeTheme].typography.font.fontFamily}; + --asg-heading-text-color: ${headingFontColor}; + --asg-primary-button-base-text-color: ${theme[theme.activeTheme].buttons.primary.base.font.color}; + --asg-primary-button-base-border-radius: ${theme[theme.activeTheme].buttons.primary.base.border.borderRadius}; + --asg-secondary-button-base-text-color: ${theme[theme.activeTheme].buttons.secondary.base.font.color}; + --asg-secondary-button-base-border-radius: ${theme[theme.activeTheme].buttons.secondary.base.border.borderRadius}; + --asg-external-login-button-base-background-color: ${ + theme[theme.activeTheme].buttons.externalConnection.base.background.backgroundColor + }; + --asg-external-login-button-base-text-color: ${theme[theme.activeTheme].buttons.externalConnection.base.font.color}; + --asg-external-login-button-base-border-radius: ${ + theme[theme.activeTheme].buttons.externalConnection.base.border.borderRadius + }; + --asg-login-box-background-color: ${ + theme[theme.activeTheme].loginBox?.background?.backgroundColor || 'var(--asg-colors-background-surface-main)' + }; + --asg-login-box-border-color: ${ + theme[theme.activeTheme].loginBox?.border?.borderColor || 'var(--asg-colors-outlined-default)' + }; + --asg-login-box-border-width: ${theme[theme.activeTheme].loginBox.border.borderWidth}; + --asg-login-box-border-style: solid; + --asg-login-box-border-radius: ${theme[theme.activeTheme].loginBox.border.borderRadius}; + --asg-login-box-text-color: ${loginBoxFontColor}; + --asg-login-page-background-color: ${ + theme[theme.activeTheme].loginPage?.background?.backgroundColor || 'var(--asg-colors-background-body-main)' + }; + --asg-login-page-font-color: ${theme[theme.activeTheme].loginPage?.font?.color || 'var(--asg-colors-text-primary)'}; + --asg-input-field-base-text-color: ${inputBaseFontColor || 'var(--asg-colors-text-primary)'}; + --asg-input-field-base-background-color: ${theme[theme.activeTheme].inputs.base.background.backgroundColor}; + --asg-input-field-base-label-text-color: ${inputBaseLabelFontColor}; + --asg-input-field-base-border-color: ${ + theme[theme.activeTheme].inputs.base.border.borderColor || 'var(--asg-colors-outlined-default)' + }; + --asg-input-field-base-border-radius: ${theme[theme.activeTheme].inputs.base.border.borderRadius}; + --language-selector-background-color: var(--asg-login-page-background-color) !important; + --language-selector-text-color: var(--asg-footer-text-color) !important; + --language-selector-border-color: var(--asg-colors-primary-main) !important; + + /* Oxygen UI variables */ + --oxygen-palette-text-primary: ${theme[theme.activeTheme].colors.text?.primary}; +} `; +}; + +export default getBrandingCSS; From 9e71074235d2fc6d940bd19e2a20b93d70a9eca4 Mon Sep 17 00:00:00 2001 From: Movin Silva Date: Mon, 6 May 2024 18:19:36 +0530 Subject: [PATCH 09/16] feat(core): :sparkles: expose branding functions --- packages/core/src/branding/public.ts | 20 ++++++++++++++++++++ packages/core/src/index.ts | 2 +- 2 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 packages/core/src/branding/public.ts diff --git a/packages/core/src/branding/public.ts b/packages/core/src/branding/public.ts new file mode 100644 index 00000000..280677f5 --- /dev/null +++ b/packages/core/src/branding/public.ts @@ -0,0 +1,20 @@ +/** + * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export {default as getBranding} from './get-branding'; +export {default as getBrandingCSS} from './get-branding-css'; diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 86e2088b..9f27cbb7 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -17,7 +17,7 @@ */ export * from './api/public-api'; -export {default as getBranding} from './branding/get-branding'; +export * from './branding/public'; export * from './i18n/public'; export * from './auth-client'; export * from './models/public-models'; From 287bf732f056e761a30765111edab63f40905748 Mon Sep 17 00:00:00 2001 From: Movin Silva Date: Mon, 6 May 2024 18:21:25 +0530 Subject: [PATCH 10/16] fix(core): :wrench: update import path style --- packages/core/src/api/logout.ts | 4 ++-- packages/core/tsconfig.json | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/core/src/api/logout.ts b/packages/core/src/api/logout.ts index f1ae730a..7a782823 100644 --- a/packages/core/src/api/logout.ts +++ b/packages/core/src/api/logout.ts @@ -16,8 +16,8 @@ * under the License. */ -import {AuthClient, ResponseMode} from 'src/auth-client'; -import AsgardeoUIException from 'src/exception'; +import {AuthClient, ResponseMode} from '../auth-client'; +import AsgardeoUIException from '../exception'; const logout = async (): Promise => { let response: Response; diff --git a/packages/core/tsconfig.json b/packages/core/tsconfig.json index 6bc65fc5..62ff812c 100644 --- a/packages/core/tsconfig.json +++ b/packages/core/tsconfig.json @@ -22,7 +22,6 @@ "noImplicitReturns": true, "noFallthroughCasesInSwitch": true, "resolveJsonModule": true, - "baseUrl": ".", "types": ["node", "jest"], }, "exclude": ["node_modules", "tmp"], From 42b2d4237bf6873da6e2f193aafc51022879b696 Mon Sep 17 00:00:00 2001 From: Movin Silva Date: Mon, 6 May 2024 18:27:29 +0530 Subject: [PATCH 11/16] docs(core): :memo: add js docs for the logout function --- packages/core/src/api/logout.ts | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/packages/core/src/api/logout.ts b/packages/core/src/api/logout.ts index 7a782823..a17da596 100644 --- a/packages/core/src/api/logout.ts +++ b/packages/core/src/api/logout.ts @@ -19,6 +19,22 @@ import {AuthClient, ResponseMode} from '../auth-client'; import AsgardeoUIException from '../exception'; +/** + * Log out the user. + * + * This function sends a logout request to the server. + * + * @returns {Promise} A promise that resolves when the logout process is complete. + * + * @example + * logout() + * .then(() => { + * console.log('Logged out!'); + * }) + * .catch((error) => { + * console.error('Failed to log out:', error); + * }); + */ const logout = async (): Promise => { let response: Response; let logoutUrl: string; From 97b0093868651a2936065710b99d93c0a21e02a0 Mon Sep 17 00:00:00 2001 From: Movin Silva Date: Tue, 7 May 2024 08:28:07 +0530 Subject: [PATCH 12/16] refactor(core): :recycle: improve getBrandingCSS function --- .../core/src/branding/get-branding-css.ts | 111 ++++++++---------- 1 file changed, 50 insertions(+), 61 deletions(-) diff --git a/packages/core/src/branding/get-branding-css.ts b/packages/core/src/branding/get-branding-css.ts index bc85214b..1ec1d5b8 100644 --- a/packages/core/src/branding/get-branding-css.ts +++ b/packages/core/src/branding/get-branding-css.ts @@ -16,103 +16,92 @@ * under the License. */ -import {BrandingPreferenceThemeInterface} from '../models/branding-api-response'; +import {BrandingPreferenceThemeInterface, ThemeConfigInterface} from '../models/branding-api-response'; import isEmpty from '../utils/is-empty'; const getBrandingCSS = (theme: BrandingPreferenceThemeInterface): string => { if (!theme) { return ''; } + const activeTheme: ThemeConfigInterface = theme[theme.activeTheme]; - const footerFontColor: string = !isEmpty(theme[theme.activeTheme].footer.font.color) - ? theme[theme.activeTheme].footer.font.color + const footerFontColor: string = !isEmpty(activeTheme.footer.font.color) ? activeTheme.footer.font.color : 'inherit'; + const headingFontColor: string = !isEmpty(activeTheme.typography.heading.font.color) + ? activeTheme.typography.heading.font.color : 'inherit'; - const headingFontColor: string = !isEmpty(theme[theme.activeTheme].typography.heading.font.color) - ? theme[theme.activeTheme].typography.heading.font.color + const loginBoxFontColor: string = !isEmpty(activeTheme.loginBox.font.color) + ? activeTheme.loginBox.font.color : 'inherit'; - const loginBoxFontColor: string = !isEmpty(theme[theme.activeTheme].loginBox.font.color) - ? theme[theme.activeTheme].loginBox.font.color + const inputBaseFontColor: string = !isEmpty(activeTheme.inputs.base.font.color) + ? activeTheme.inputs.base.font.color : 'inherit'; - const inputBaseFontColor: string = !isEmpty(theme[theme.activeTheme].inputs.base.font.color) - ? theme[theme.activeTheme].inputs.base.font.color - : 'inherit'; - const inputBaseLabelFontColor: string = !isEmpty(theme[theme.activeTheme].inputs.base.labels.font.color) - ? theme[theme.activeTheme].inputs.base.labels.font.color + const inputBaseLabelFontColor: string = !isEmpty(activeTheme.inputs.base.labels.font.color) + ? activeTheme.inputs.base.labels.font.color : 'inherit'; return ` - ${ - theme[theme.activeTheme].typography.font.importURL - ? `@import url(${theme[theme.activeTheme].typography.font.importURL});` - : '' - } + ${activeTheme.typography.font.importURL ? `@import url(${activeTheme.typography.font.importURL});` : ''} :root { - --asg-colors-primary-main: ${theme[theme.activeTheme].colors.primary.main}; - --asg-colors-secondary-main: ${theme[theme.activeTheme].colors.secondary.main}; - --asg-colors-background-body-main: ${theme[theme.activeTheme].colors.background?.body?.main}; - --asg-colors-background-surface-main: ${theme[theme.activeTheme].colors.background?.surface?.main}; - --asg-colors-background-surface-light: ${theme[theme.activeTheme].colors.background?.surface?.light}; - --asg-colors-background-surface-dark: ${theme[theme.activeTheme].colors.background?.surface?.dark}; - --asg-colors-background-surface-inverted: ${theme[theme.activeTheme].colors.background?.surface?.inverted}; - --asg-colors-outlined-default: ${theme[theme.activeTheme].colors.outlined?.default}; - --asg-colors-text-primary: ${theme[theme.activeTheme].colors.text?.primary}; - --asg-colors-text-secondary: ${theme[theme.activeTheme].colors.text?.secondary}; - --asg-colors-alerts-error-main: ${theme[theme.activeTheme].colors.alerts?.error?.main}; - --asg-colors-alerts-neutral-main: ${theme[theme.activeTheme].colors.alerts?.neutral?.main}; - --asg-colors-alerts-info-main: ${theme[theme.activeTheme].colors.alerts?.info?.main}; - --asg-colors-alerts-warning-main: ${theme[theme.activeTheme].colors.alerts?.warning?.main}; - --asg-colors-illustrations-primary-main: ${theme[theme.activeTheme].colors.illustrations?.primary?.main}; - --asg-colors-illustrations-secondary-main: ${theme[theme.activeTheme].colors.illustrations?.secondary?.main}; - --asg-colors-illustrations-accent1-main: ${theme[theme.activeTheme].colors.illustrations?.accent1?.main}; - --asg-colors-illustrations-accent2-main: ${theme[theme.activeTheme].colors.illustrations?.accent2?.main}; - --asg-colors-illustrations-accent3-main: ${theme[theme.activeTheme].colors.illustrations?.accent3?.main}; + --asg-colors-primary-main: ${activeTheme.colors.primary.main}; + --asg-colors-secondary-main: ${activeTheme.colors.secondary.main}; + --asg-colors-background-body-main: ${activeTheme.colors.background?.body?.main}; + --asg-colors-background-surface-main: ${activeTheme.colors.background?.surface?.main}; + --asg-colors-background-surface-light: ${activeTheme.colors.background?.surface?.light}; + --asg-colors-background-surface-dark: ${activeTheme.colors.background?.surface?.dark}; + --asg-colors-background-surface-inverted: ${activeTheme.colors.background?.surface?.inverted}; + --asg-colors-outlined-default: ${activeTheme.colors.outlined?.default}; + --asg-colors-text-primary: ${activeTheme.colors.text?.primary}; + --asg-colors-text-secondary: ${activeTheme.colors.text?.secondary}; + --asg-colors-alerts-error-main: ${activeTheme.colors.alerts?.error?.main}; + --asg-colors-alerts-neutral-main: ${activeTheme.colors.alerts?.neutral?.main}; + --asg-colors-alerts-info-main: ${activeTheme.colors.alerts?.info?.main}; + --asg-colors-alerts-warning-main: ${activeTheme.colors.alerts?.warning?.main}; + --asg-colors-illustrations-primary-main: ${activeTheme.colors.illustrations?.primary?.main}; + --asg-colors-illustrations-secondary-main: ${activeTheme.colors.illustrations?.secondary?.main}; + --asg-colors-illustrations-accent1-main: ${activeTheme.colors.illustrations?.accent1?.main}; + --asg-colors-illustrations-accent2-main: ${activeTheme.colors.illustrations?.accent2?.main}; + --asg-colors-illustrations-accent3-main: ${activeTheme.colors.illustrations?.accent3?.main}; /* Components */ --asg-footer-text-color: ${footerFontColor}; - --asg-footer-border-color: ${ - theme[theme.activeTheme].footer?.border?.borderColor || 'var(--asg-colors-outlined-default)' - }; - --asg-primary-font-family: ${theme[theme.activeTheme].typography.font.fontFamily}; + --asg-footer-border-color: ${activeTheme.footer?.border?.borderColor || 'var(--asg-colors-outlined-default)'}; + --asg-primary-font-family: ${activeTheme.typography.font.fontFamily}; --asg-heading-text-color: ${headingFontColor}; - --asg-primary-button-base-text-color: ${theme[theme.activeTheme].buttons.primary.base.font.color}; - --asg-primary-button-base-border-radius: ${theme[theme.activeTheme].buttons.primary.base.border.borderRadius}; - --asg-secondary-button-base-text-color: ${theme[theme.activeTheme].buttons.secondary.base.font.color}; - --asg-secondary-button-base-border-radius: ${theme[theme.activeTheme].buttons.secondary.base.border.borderRadius}; + --asg-primary-button-base-text-color: ${activeTheme.buttons.primary.base.font.color}; + --asg-primary-button-base-border-radius: ${activeTheme.buttons.primary.base.border.borderRadius}; + --asg-secondary-button-base-text-color: ${activeTheme.buttons.secondary.base.font.color}; + --asg-secondary-button-base-border-radius: ${activeTheme.buttons.secondary.base.border.borderRadius}; --asg-external-login-button-base-background-color: ${ - theme[theme.activeTheme].buttons.externalConnection.base.background.backgroundColor - }; - --asg-external-login-button-base-text-color: ${theme[theme.activeTheme].buttons.externalConnection.base.font.color}; - --asg-external-login-button-base-border-radius: ${ - theme[theme.activeTheme].buttons.externalConnection.base.border.borderRadius + activeTheme.buttons.externalConnection.base.background.backgroundColor }; + --asg-external-login-button-base-text-color: ${activeTheme.buttons.externalConnection.base.font.color}; + --asg-external-login-button-base-border-radius: ${activeTheme.buttons.externalConnection.base.border.borderRadius}; --asg-login-box-background-color: ${ - theme[theme.activeTheme].loginBox?.background?.backgroundColor || 'var(--asg-colors-background-surface-main)' - }; - --asg-login-box-border-color: ${ - theme[theme.activeTheme].loginBox?.border?.borderColor || 'var(--asg-colors-outlined-default)' + activeTheme.loginBox?.background?.backgroundColor || 'var(--asg-colors-background-surface-main)' }; - --asg-login-box-border-width: ${theme[theme.activeTheme].loginBox.border.borderWidth}; + --asg-login-box-border-color: ${activeTheme.loginBox?.border?.borderColor || 'var(--asg-colors-outlined-default)'}; + --asg-login-box-border-width: ${activeTheme.loginBox.border.borderWidth}; --asg-login-box-border-style: solid; - --asg-login-box-border-radius: ${theme[theme.activeTheme].loginBox.border.borderRadius}; + --asg-login-box-border-radius: ${activeTheme.loginBox.border.borderRadius}; --asg-login-box-text-color: ${loginBoxFontColor}; --asg-login-page-background-color: ${ - theme[theme.activeTheme].loginPage?.background?.backgroundColor || 'var(--asg-colors-background-body-main)' + activeTheme.loginPage?.background?.backgroundColor || 'var(--asg-colors-background-body-main)' }; - --asg-login-page-font-color: ${theme[theme.activeTheme].loginPage?.font?.color || 'var(--asg-colors-text-primary)'}; + --asg-login-page-font-color: ${activeTheme.loginPage?.font?.color || 'var(--asg-colors-text-primary)'}; --asg-input-field-base-text-color: ${inputBaseFontColor || 'var(--asg-colors-text-primary)'}; - --asg-input-field-base-background-color: ${theme[theme.activeTheme].inputs.base.background.backgroundColor}; + --asg-input-field-base-background-color: ${activeTheme.inputs.base.background.backgroundColor}; --asg-input-field-base-label-text-color: ${inputBaseLabelFontColor}; --asg-input-field-base-border-color: ${ - theme[theme.activeTheme].inputs.base.border.borderColor || 'var(--asg-colors-outlined-default)' + activeTheme.inputs.base.border.borderColor || 'var(--asg-colors-outlined-default)' }; - --asg-input-field-base-border-radius: ${theme[theme.activeTheme].inputs.base.border.borderRadius}; + --asg-input-field-base-border-radius: ${activeTheme.inputs.base.border.borderRadius}; --language-selector-background-color: var(--asg-login-page-background-color) !important; --language-selector-text-color: var(--asg-footer-text-color) !important; --language-selector-border-color: var(--asg-colors-primary-main) !important; /* Oxygen UI variables */ - --oxygen-palette-text-primary: ${theme[theme.activeTheme].colors.text?.primary}; + --oxygen-palette-text-primary: ${activeTheme.colors.text?.primary}; } `; }; From ea330fd3e8dbfe2b3154ea00776a04fc87c336f9 Mon Sep 17 00:00:00 2001 From: Movin Silva Date: Tue, 7 May 2024 09:14:42 +0530 Subject: [PATCH 13/16] fix(core): :label: update type in Customization interface --- packages/core/src/models/customization.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/src/models/customization.ts b/packages/core/src/models/customization.ts index b3f37bc3..2a1fc058 100644 --- a/packages/core/src/models/customization.ts +++ b/packages/core/src/models/customization.ts @@ -45,7 +45,7 @@ export interface Customization { /** * Preference type. */ - type?: RecursivePartial; + type?: BrandingPreferenceTypes; } /** From 0792b1ffb9cca60c579761932049b07790eb53e6 Mon Sep 17 00:00:00 2001 From: Movin Silva Date: Tue, 7 May 2024 14:31:25 +0530 Subject: [PATCH 14/16] refactor(core): :recycle: change the logout to signout --- .../core/src/api/{logout.ts => sign-out.ts} | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) rename packages/core/src/api/{logout.ts => sign-out.ts} (62%) diff --git a/packages/core/src/api/logout.ts b/packages/core/src/api/sign-out.ts similarity index 62% rename from packages/core/src/api/logout.ts rename to packages/core/src/api/sign-out.ts index a17da596..c5f4b771 100644 --- a/packages/core/src/api/logout.ts +++ b/packages/core/src/api/sign-out.ts @@ -20,24 +20,24 @@ import {AuthClient, ResponseMode} from '../auth-client'; import AsgardeoUIException from '../exception'; /** - * Log out the user. + * Sign out the user. * - * This function sends a logout request to the server. + * This function sends a signout request to the server. * - * @returns {Promise} A promise that resolves when the logout process is complete. + * @returns {Promise} A promise that resolves when the sign out process is complete. * * @example - * logout() + * signOut() * .then(() => { - * console.log('Logged out!'); + * console.log('Signed out!'); * }) * .catch((error) => { - * console.error('Failed to log out:', error); + * console.error('Failed to sign out:', error); * }); */ -const logout = async (): Promise => { +const signOut = async (): Promise => { let response: Response; - let logoutUrl: string; + let signOutUrl: string; const headers: Headers = new Headers(); headers.append('Accept', 'application/json'); @@ -50,7 +50,7 @@ const logout = async (): Promise => { formBody.append('client_id', (await AuthClient.getInstance().getDataLayer().getConfigData()).clientID); formBody.append('response_mode', ResponseMode.direct); } catch (error) { - throw new AsgardeoUIException('JS_UI_CORE-LOGOUT-L-IV', 'Failed to build the body of the logout request.'); + throw new AsgardeoUIException('JS_UI_CORE-SIGNOUT-SO-IV', 'Failed to build the body of the signout request.'); } const requestOptions: RequestInit = { @@ -60,23 +60,23 @@ const logout = async (): Promise => { }; try { - logoutUrl = (await AuthClient.getInstance().getOIDCServiceEndpoints()).endSessionEndpoint; + signOutUrl = (await AuthClient.getInstance().getOIDCServiceEndpoints()).endSessionEndpoint; } catch (error) { - throw new AsgardeoUIException('JS_UI_CORE-LOGOUT-L-NF', 'Failed to retrieve the logout endpoint.'); + throw new AsgardeoUIException('JS_UI_CORE-SIGNOUT-SO-NF', 'Failed to retrieve the sign out endpoint.'); } try { - response = await fetch(logoutUrl, requestOptions); + response = await fetch(signOutUrl, requestOptions); } catch (error) { - throw new AsgardeoUIException('JS_UI_CORE-LOGOUT-L-NE', 'Failed to send a request to the logout endpoint.'); + throw new AsgardeoUIException('JS_UI_CORE-SIGNOUT-SO-NE', 'Failed to send a request to the sign out endpoint.'); } if (!response.ok) { throw new AsgardeoUIException( - 'JS_UI_CORE-LOGOUT-L-HE', - 'Failed to receive a successful response from the logout endpoint.', + 'JS_UI_CORE-SIGNOUT-SO-HE', + 'Failed to receive a successful response from the sign out endpoint.', ); } }; -export default logout; +export default signOut; From 395e7ef714c150095c607dbac975bfbea02be4ff Mon Sep 17 00:00:00 2001 From: Movin Silva Date: Tue, 7 May 2024 14:33:37 +0530 Subject: [PATCH 15/16] feat(core): :sparkles: export signout function --- packages/core/src/api/public-api.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/core/src/api/public-api.ts b/packages/core/src/api/public-api.ts index 2e22aef2..0eef3ae9 100644 --- a/packages/core/src/api/public-api.ts +++ b/packages/core/src/api/public-api.ts @@ -21,3 +21,4 @@ export {default as authenticate} from './authenticate'; export {default as getBrandingPreference} from './get-branding-preference'; export {default as getProfileInformation} from './get-profile-information'; export {default as getBrandingPreferenceText} from './get-branding-preference-text'; +export {default as signOut} from './sign-out'; From 48dc84f883bdf4d42f3739dcad2c0bf4cd3691b3 Mon Sep 17 00:00:00 2001 From: Movin Silva Date: Tue, 7 May 2024 14:39:41 +0530 Subject: [PATCH 16/16] refactor(core): :heavy_plus_sign: add lodash isEmpty package and replace the current isEmpty implementation --- packages/core/package.json | 2 + .../core/src/branding/get-branding-css.ts | 2 +- packages/core/src/utils/is-empty.ts | 55 ------------------- pnpm-lock.yaml | 16 ++++++ 4 files changed, 19 insertions(+), 56 deletions(-) delete mode 100644 packages/core/src/utils/is-empty.ts diff --git a/packages/core/package.json b/packages/core/package.json index 3a3e11b2..b921c6b9 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -36,6 +36,7 @@ "@rollup/plugin-dynamic-import-vars": "^2.1.2", "@rollup/plugin-node-resolve": "^15.2.3", "@rollup/plugin-typescript": "^11.1.6", + "@types/lodash.isempty": "^4.4.9", "@types/lodash.merge": "^4.6.9", "@types/node": "^20.12.7", "@wso2/eslint-plugin": "https://gitpkg.now.sh/brionmario/wso2-ui-configs/packages/eslint-plugin?fa0b844715320a3953d6d055997c0770f8695082", @@ -52,6 +53,7 @@ "dependencies": { "@asgardeo/auth-js": "^5.0.1", "csstype": "^3.1.3", + "lodash.isempty": "^4.4.0", "lodash.merge": "^4.6.2" } } diff --git a/packages/core/src/branding/get-branding-css.ts b/packages/core/src/branding/get-branding-css.ts index 1ec1d5b8..c0219905 100644 --- a/packages/core/src/branding/get-branding-css.ts +++ b/packages/core/src/branding/get-branding-css.ts @@ -17,7 +17,7 @@ */ import {BrandingPreferenceThemeInterface, ThemeConfigInterface} from '../models/branding-api-response'; -import isEmpty from '../utils/is-empty'; +import isEmpty from 'lodash.isempty'; const getBrandingCSS = (theme: BrandingPreferenceThemeInterface): string => { if (!theme) { diff --git a/packages/core/src/utils/is-empty.ts b/packages/core/src/utils/is-empty.ts deleted file mode 100644 index d7922785..00000000 --- a/packages/core/src/utils/is-empty.ts +++ /dev/null @@ -1,55 +0,0 @@ -/** - * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). - * - * WSO2 LLC. licenses this file to you under the Apache License, - * Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -/** - * Checks if the given value is empty. - * - * @param {unknown} value - The value to check. - * @returns {boolean} Returns `true` if the value is empty, otherwise `false`. - * - * @example - * isEmpty(null); // => true - * isEmpty(''); // => true - * isEmpty([]); // => true - * isEmpty({}); // => true - * isEmpty('Hello'); // => false - * isEmpty([1, 2, 3]); // => false - * isEmpty({ a: 1 }); // => false - */ -const isEmpty = (value: unknown): boolean => { - /** - * If the value is null or undefined, return true. - */ - if (value === null || undefined) { - return true; - } - - /** - * If the value is a string or an array, check if it's length is 0. If it is, return true. - */ - if (typeof value === 'string' || Array.isArray(value)) { - return value.length === 0; - } - - /** - * If the value is an object, check if it has any keys. If it doesn't, return true. - */ - return Object.keys(value).length === 0; -}; - -export default isEmpty; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e39731a9..cfb9d89b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -20,6 +20,9 @@ importers: csstype: specifier: ^3.1.3 version: 3.1.3 + lodash.isempty: + specifier: ^4.4.0 + version: 4.4.0 lodash.merge: specifier: ^4.6.2 version: 4.6.2 @@ -36,6 +39,9 @@ importers: '@rollup/plugin-typescript': specifier: ^11.1.6 version: 11.1.6(rollup@4.16.4)(tslib@2.6.2)(typescript@5.4.5) + '@types/lodash.isempty': + specifier: ^4.4.9 + version: 4.4.9 '@types/lodash.merge': specifier: ^4.6.9 version: 4.6.9 @@ -858,6 +864,12 @@ packages: resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} dev: true + /@types/lodash.isempty@4.4.9: + resolution: {integrity: sha512-DPSFfnT2JmZiAWNWOU8IRZws/Ha6zyGF5m06TydfsY+0dVoQqby2J61Na2QU4YtwiZ+moC6cJS6zWYBJq4wBVw==} + dependencies: + '@types/lodash': 4.17.0 + dev: true + /@types/lodash.merge@4.6.9: resolution: {integrity: sha512-23sHDPmzd59kUgWyKGiOMO2Qb9YtqRO/x4IhkgNUiPQ1+5MUVqi6bCZeq9nBJ17msjIMbEIO5u+XW4Kz6aGUhQ==} dependencies: @@ -3116,6 +3128,10 @@ packages: p-locate: 5.0.0 dev: true + /lodash.isempty@4.4.0: + resolution: {integrity: sha512-oKMuF3xEeqDltrGMfDxAPGIVMSSRv8tbRSODbrs4KGsRRLEhrW8N8Rd4DRgB2+621hY8A8XwwrTVhXWpxFvMzg==} + dev: false + /lodash.merge@4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}