@cayuse-test/react 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +346 -0
- package/dist/chunk-2K3CWMLR.js +108 -0
- package/dist/chunk-2K3CWMLR.js.map +1 -0
- package/dist/chunk-B2Z63U4D.js +10398 -0
- package/dist/chunk-B2Z63U4D.js.map +1 -0
- package/dist/chunk-EPGO6B3U.js +3 -0
- package/dist/chunk-EPGO6B3U.js.map +1 -0
- package/dist/chunk-LFWPG3ND.js +97 -0
- package/dist/chunk-LFWPG3ND.js.map +1 -0
- package/dist/chunk-M2L7SQBQ.js +205 -0
- package/dist/chunk-M2L7SQBQ.js.map +1 -0
- package/dist/chunk-MJBMK4OG.js +143 -0
- package/dist/chunk-MJBMK4OG.js.map +1 -0
- package/dist/chunk-RG4GEORO.js +194 -0
- package/dist/chunk-RG4GEORO.js.map +1 -0
- package/dist/chunk-SZMEZFAR.js +193 -0
- package/dist/chunk-SZMEZFAR.js.map +1 -0
- package/dist/chunk-TYZPOXN5.js +243 -0
- package/dist/chunk-TYZPOXN5.js.map +1 -0
- package/dist/chunk-XRUFEGUC.js +225 -0
- package/dist/chunk-XRUFEGUC.js.map +1 -0
- package/dist/components/index.d.ts +1471 -0
- package/dist/components/index.js +144 -0
- package/dist/components/index.js.map +1 -0
- package/dist/context/tenant/index.d.ts +200 -0
- package/dist/context/tenant/index.js +14 -0
- package/dist/context/tenant/index.js.map +1 -0
- package/dist/globals/constants/index.d.ts +83 -0
- package/dist/globals/constants/index.js +31 -0
- package/dist/globals/constants/index.js.map +1 -0
- package/dist/globals/css/index.d.ts +2 -0
- package/dist/globals/css/index.js +2 -0
- package/dist/globals/css/index.js.map +1 -0
- package/dist/hooks/index.d.ts +125 -0
- package/dist/hooks/index.js +30 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/index-4NH7IW34.css +47 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.js +302 -0
- package/dist/index.js.map +1 -0
- package/dist/modal-dialog-IH5SI4CF.css +93 -0
- package/dist/services/upload-s3/index.d.ts +35 -0
- package/dist/services/upload-s3/index.js +11 -0
- package/dist/services/upload-s3/index.js.map +1 -0
- package/dist/styles-2WZORUGA.css +106 -0
- package/dist/styles-32VHTPIA.css +20 -0
- package/dist/styles-3A5DZ5R7.css +70 -0
- package/dist/styles-3PFCZALV.css +60 -0
- package/dist/styles-3SNYRDO2.css +100 -0
- package/dist/styles-4FHUBUVF.css +150 -0
- package/dist/styles-4KAVAZFG.css +5 -0
- package/dist/styles-4OFM6DY5.css +22 -0
- package/dist/styles-5OXZHQGW.css +14 -0
- package/dist/styles-6XZTUN3B.css +68 -0
- package/dist/styles-73WOPK6M.css +6 -0
- package/dist/styles-7AV26IBF.css +35 -0
- package/dist/styles-7DWK55L2.css +71 -0
- package/dist/styles-7GWPZSR2.css +222 -0
- package/dist/styles-7QBPXFSY.css +6 -0
- package/dist/styles-7T6DSZIY.css +27 -0
- package/dist/styles-AUI7W2SW.css +408 -0
- package/dist/styles-AZSHBXJQ.css +85 -0
- package/dist/styles-BTXJVGNW.css +99 -0
- package/dist/styles-BUPIQG5C.css +74 -0
- package/dist/styles-CLK36LUK.css +27 -0
- package/dist/styles-CSKYCMD4.css +123 -0
- package/dist/styles-CWCX26BQ.css +13 -0
- package/dist/styles-GAIKDZU6.css +47 -0
- package/dist/styles-GB7S5BAZ.css +36 -0
- package/dist/styles-GVPT6A2Z.css +45 -0
- package/dist/styles-IUBOTHBR.css +581 -0
- package/dist/styles-IZPTZRKW.css +78 -0
- package/dist/styles-LS2YWO5W.css +39 -0
- package/dist/styles-M5BEFS4G.css +148 -0
- package/dist/styles-MHNICXOS.css +18 -0
- package/dist/styles-P6IOJDNI.css +47 -0
- package/dist/styles-Q7XE2QVU.css +55 -0
- package/dist/styles-R7IS5IGF.css +7 -0
- package/dist/styles-RDYYTTBU.css +218 -0
- package/dist/styles-RTHIZL5W.css +48 -0
- package/dist/styles-RUY4EKZW.css +9 -0
- package/dist/styles-T5QJAAUY.css +184 -0
- package/dist/styles-VBXWGFCK.css +96 -0
- package/dist/styles-VE76CGRO.css +6 -0
- package/dist/styles-VLCZ7JYV.css +140 -0
- package/dist/styles-W5HDD3YQ.css +71 -0
- package/dist/styles-X7BJCSFV.css +86 -0
- package/dist/styles-XVRR5GIG.css +42 -0
- package/dist/styles-YBC6BJBD.css +83 -0
- package/dist/styles-YXNJHPDZ.css +74 -0
- package/dist/styles-Z276IEVM.css +264 -0
- package/dist/utils/index.d.ts +145 -0
- package/dist/utils/index.js +98 -0
- package/dist/utils/index.js.map +1 -0
- package/package.json +113 -0
- package/packages/eslint-config/README.md +69 -0
- package/packages/eslint-config/base.js +25 -0
- package/packages/eslint-config/next.js +49 -0
- package/packages/eslint-config/react-internal.js +44 -0
- package/packages/typescript-config/README.md +70 -0
- package/packages/typescript-config/base.json +21 -0
- package/packages/typescript-config/nextjs.json +12 -0
- package/packages/typescript-config/react-library.json +7 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../packages/hooks/use-file-uploader/uppy/constants.ts","../packages/hooks/use-file-uploader/uppy/api.ts","../packages/hooks/use-file-uploader/uppy/service.ts","../packages/hooks/use-click-outside/use-click-outside.tsx"],"sourcesContent":["export type UppyEvent =\n\t| 'file-added'\n\t| 'files-added'\n\t| 'file-removed'\n\t| 'upload'\n\t| 'progress'\n\t| 'preprocess-complete'\n\t| 'upload-progress'\n\t| 'upload-success'\n\t| 'complete'\n\t| 'error'\n\t| 'upload-error'\n\t| 'upload-retry'\n\t| 'retry-all'\n\t| 'info-visible'\n\t| 'info-hidden'\n\t| 'cancel-all'\n\t| 'restriction-failed'\n\t| 'reset-progress';\n\nexport const uppyEvents: UppyEvent[] = [\n\t'file-added',\n\t'files-added',\n\t'file-removed',\n\t'upload',\n\t'progress',\n\t'preprocess-complete',\n\t'upload-progress',\n\t'upload-success',\n\t'complete',\n\t'error',\n\t'upload-error',\n\t'upload-retry',\n\t'retry-all',\n\t'info-visible',\n\t'info-hidden',\n\t'cancel-all',\n\t'restriction-failed',\n\t'reset-progress',\n];\n\ninterface UppyState {\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tplugins: { [key: string]: any };\n\terror: string;\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tfiles: { [key: string]: any };\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tcurrentUploads: { [key: string]: any };\n\tallowNewUpload: boolean;\n\tcapabilities: {\n\t\tuploadProgress: boolean;\n\t\tindividualCancellation: boolean;\n\t\tresumableUploads: boolean;\n\t};\n\ttotalProgress: number;\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tmeta: { [key: string]: any };\n\tinfo: Array<{ type: string; message: string; details: string }>;\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\trecoveredState: null | { [key: string]: any };\n}\n\nexport const uppyInitialState: UppyState = {\n\tplugins: {},\n\terror: '',\n\tfiles: {},\n\tcurrentUploads: {},\n\tallowNewUpload: true,\n\tcapabilities: {\n\t\tuploadProgress: true,\n\t\tindividualCancellation: true,\n\t\tresumableUploads: false,\n\t},\n\ttotalProgress: 0,\n\tmeta: {},\n\tinfo: [],\n\trecoveredState: null,\n};\n\nexport const MAX_FILE_SIZE_75_MB: number = 75 * Math.pow(1024, 2);\n\ninterface DefaultDictionary {\n\texeFileTypeRestriction: string;\n\t[key: string]: string;\n}\n\nexport const defaultDictionary: DefaultDictionary = {\n\texeFileTypeRestriction:\n\t\t'Attachments with filetype .exe cannot be accepted. Please try a different file type.',\n};\n","import { executeRequest } from '@/utils/http';\n\ninterface UploadUrlResponse {\n\tpreSignedUrl: string;\n\tuploadMetadataId: string;\n}\n\ninterface CompleteUploadResponse {\n\tcompletedAt: string;\n\tcreatedAt: string;\n\tfileName: string;\n\tfileSize: number;\n\tfinalizedAt: unknown;\n\tid: string;\n\ttenantId: string;\n\tuploadedBy: string;\n}\n\ninterface PersonDetails {\n\tid: string;\n\ttenantId: string;\n\tfirstName: string;\n\tlastName: string;\n\tfullName: string;\n\tmiddleName: string;\n\tcontactEmail: string;\n\tuserAccountId: string;\n}\n\ninterface UploadUrlRequestBody {\n\tfileName: string;\n\tfileSize: number;\n}\n\ninterface RequestOptions {\n\tsignal?: AbortSignal;\n}\n\nexport const api = {\n\tgetUploadURL: (\n\t\tbody: UploadUrlRequestBody,\n\t\toptions?: RequestOptions,\n\t): Promise<UploadUrlResponse> => {\n\t\tconst requestOptions = {\n\t\t\tmethod: 'POST',\n\t\t\tbody: JSON.stringify(body),\n\t\t\theaders: { 'Content-Type': 'application/json' },\n\t\t\tsignal: options?.signal,\n\t\t};\n\n\t\treturn executeRequest('/api/v2/attachments/upload', requestOptions);\n\t},\n\n\tcompleteUpload: (id: string): Promise<CompleteUploadResponse> => {\n\t\tconst requestOptions = {\n\t\t\tmethod: 'POST',\n\t\t};\n\n\t\treturn executeRequest(\n\t\t\t`/api/v2/attachments/upload/${id}/complete`,\n\t\t\trequestOptions,\n\t\t);\n\t},\n\n\tgetDownloadUrl: (id: string): Promise<string> => {\n\t\treturn executeRequest(`/api/v2/attachments/download?uploadMetadataId=${id}`);\n\t},\n\n\tgetPersonDetailsById: (\n\t\tid: string,\n\t): Promise<PersonDetails | { errors: unknown[] }> => {\n\t\treturn executeRequest(`/api/v2/person/user/${id}`);\n\t},\n};\n","import { v4 as uuidv4 } from 'uuid';\nimport Uppy from '@uppy/core';\nimport AwsS3 from '@uppy/aws-s3';\nimport { merge } from 'lodash-es';\n\nimport { MAX_FILE_SIZE_75_MB, uppyEvents, UppyEvent } from './constants.js';\nimport { api } from './api.js';\n\ninterface UppyDefaultOptions {\n\tautoProceed?: boolean;\n\trestrictions?: {\n\t\tmaxFileSize?: number;\n\t\tmaxNumberOfFiles?: number;\n\t\tallowedFileTypes?: string[] | null;\n\t};\n}\n\ninterface UppyFile {\n\tid: string;\n\tname: string;\n\tsize: number;\n\ttype: string;\n\tmeta: {\n\t\tuploadMetadataId: string;\n\t\tuploadedBy: string;\n\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\t\t[key: string]: any;\n\t};\n}\n\ninterface UploadUrlResponse {\n\tpreSignedUrl: string;\n\tuploadMetadataId: string;\n}\n\ninterface CompleteUploadResponse {\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\t[k: string]: any;\n\tcompletedAt: string;\n\tcreatedAt: string;\n\tfileName: string;\n\tfileSize: number;\n\tfinalizedAt: unknown;\n\tid: string;\n\ttenantId: string;\n\tuploadedBy: string;\n}\n\ninterface PersonDetails {\n\tfirstName: string;\n\tlastName: string;\n}\n\nexport class UppyService {\n\tprivate instances: Map<string, Uppy> = new Map();\n\tprivate retryCount: number = 0;\n\tprivate defaultOptions: UppyDefaultOptions = {\n\t\tautoProceed: true,\n\t\trestrictions: {\n\t\t\tmaxFileSize: MAX_FILE_SIZE_75_MB,\n\t\t\tmaxNumberOfFiles: 9,\n\t\t\tallowedFileTypes: null,\n\t\t},\n\t};\n\n\tgetInstance(id: string): Uppy | null {\n\t\treturn this.instances.get(id) || null;\n\t}\n\n\tregister(options: UppyDefaultOptions): Uppy {\n\t\tconst id: string = uuidv4();\n\n\t\tconst getUploadParameters =\n\t\t\t(instanceId: string) =>\n\t\t\tasync (\n\t\t\t\tfile: UppyFile,\n\t\t\t\t_options: { signal?: AbortSignal },\n\t\t\t): Promise<{\n\t\t\t\tmethod: string;\n\t\t\t\turl: string;\n\t\t\t\tfields: Record<string, never>;\n\t\t\t\theaders: { 'Content-Type': string };\n\t\t\t}> => {\n\t\t\t\tconst response: UploadUrlResponse = await api.getUploadURL(\n\t\t\t\t\t{\n\t\t\t\t\t\tfileName: file.name,\n\t\t\t\t\t\tfileSize: file.size,\n\t\t\t\t\t},\n\t\t\t\t\t_options,\n\t\t\t\t);\n\n\t\t\t\tconst instance = this.getInstance(instanceId);\n\t\t\t\tif (instance) {\n\t\t\t\t\t// @ts-expect-error type mismatch\n\t\t\t\t\tinstance.setFileMeta(file.id, response);\n\t\t\t\t}\n\n\t\t\t\treturn {\n\t\t\t\t\tmethod: 'PUT',\n\t\t\t\t\turl: response.preSignedUrl,\n\t\t\t\t\tfields: {},\n\t\t\t\t\theaders: {\n\t\t\t\t\t\t'Content-Type': file.type,\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t};\n\n\t\tconst instance: Uppy = new Uppy(this.#getOptions(id, options)).use(AwsS3, {\n\t\t\t// @ts-expect-error type mismatch\n\t\t\tgetUploadParameters: getUploadParameters(id),\n\t\t});\n\n\t\tObject.defineProperty(instance, 'id', { value: id, enumerable: true });\n\n\t\tthis.instances.set(id, instance);\n\n\t\tthis.#subscribeOnEvents(id);\n\n\t\treturn instance;\n\t}\n\n\tdestroy(id: string): void {\n\t\tconst instance = this.getInstance(id);\n\t\t// @ts-expect-error type mismatch\n\t\tinstance?.close(() => this.instances.delete(id));\n\t}\n\n\tonAnyEvent(\n\t\tid: string,\n\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\t\teventCallback: (eventName: UppyEvent, ...args: any[]) => void,\n\t): void {\n\t\tconst inst = this.getInstance(id);\n\t\tif (inst) {\n\t\t\tuppyEvents.forEach((event: UppyEvent) => {\n\t\t\t\tinst.on(\n\t\t\t\t\t// @ts-expect-error type mismatch\n\t\t\t\t\tevent,\n\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\t\t\t\t\t(...args: any[]) => {\n\t\t\t\t\t\teventCallback(event, ...args);\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t});\n\t\t}\n\t}\n\n\t#subscribeOnEvents(instanceId: string): void {\n\t\tconst instance = this.getInstance(instanceId);\n\t\tif (instance) {\n\t\t\t// @ts-expect-error type miss match\n\t\t\tinstance.on('upload-success', async (file: UppyFile) => {\n\t\t\t\tawait this.#completeUploading(instanceId, file);\n\t\t\t});\n\t\t}\n\t}\n\n\t#getOptions(\n\t\tid: string,\n\t\toptions: UppyDefaultOptions,\n\t): UppyDefaultOptions & { id: string; debug: boolean } {\n\t\treturn {\n\t\t\t...merge(this.defaultOptions, options),\n\t\t\tid,\n\t\t\tdebug: true,\n\t\t};\n\t}\n\n\tasync #completeUploading(instanceId: string, file: UppyFile): Promise<void> {\n\t\tconst instance = this.getInstance(instanceId);\n\t\tif (!instance) return;\n\n\t\ttry {\n\t\t\tconst completedResponse: CompleteUploadResponse = await api.completeUpload(\n\t\t\t\tfile.meta.uploadMetadataId,\n\t\t\t);\n\t\t\tinstance.setFileMeta(file.id, completedResponse);\n\n\t\t\tinstance.emit('complete', completedResponse);\n\n\t\t\tthis.#getDownloadUrl(instanceId, file.id);\n\t\t\tthis.#loadAdditionalFileMetadata(instanceId, file.id);\n\t\t} catch (error) {\n\t\t\t// @ts-expect-error type miss match\n\t\t\tinstance.emit('upload-error', file, error);\n\t\t}\n\t}\n\n\tasync #getDownloadUrl(instanceId: string, fileId: string): Promise<void> {\n\t\tconst instance = this.getInstance(instanceId);\n\t\tif (!instance) return;\n\n\t\ttry {\n\t\t\tconst file = instance.getFile(fileId);\n\t\t\tif (!file) return;\n\n\t\t\tconst downloadUrl: string = await api.getDownloadUrl(\n\t\t\t\tfile.meta.uploadMetadataId as string,\n\t\t\t);\n\n\t\t\tif (typeof downloadUrl === 'string') {\n\t\t\t\tinstance.setFileMeta(fileId, { downloadUrl });\n\t\t\t} else {\n\t\t\t\tinstance.emit('error', downloadUrl);\n\t\t\t}\n\n\t\t\tinstance.emit('complete', { downloadUrl });\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\t\t} catch (error: any) {\n\t\t\tinstance.emit('error', error);\n\t\t}\n\t}\n\n\tasync #loadAdditionalFileMetadata(\n\t\tinstanceId: string,\n\t\tfileId: string,\n\t): Promise<void> {\n\t\tconst instance = this.getInstance(instanceId);\n\t\tif (!instance) return;\n\n\t\ttry {\n\t\t\tconst file = instance.getFile(fileId);\n\t\t\tif (!file) return;\n\n\t\t\tconst response: PersonDetails | { errors: unknown[] } =\n\t\t\t\tawait api.getPersonDetailsById(file.meta.uploadedBy as string);\n\n\t\t\tif ('firstName' in response) {\n\t\t\t\tinstance.setFileMeta(fileId, {\n\t\t\t\t\tuploadedByInfo: {\n\t\t\t\t\t\tfirstName: response.firstName,\n\t\t\t\t\t\tlastName: response.lastName,\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\t\t\t\tinstance.emit('error', response as any);\n\t\t\t}\n\n\t\t\tinstance.emit('complete', {});\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\t\t} catch (error: any) {\n\t\t\tinstance.emit('error', error);\n\t\t}\n\t}\n}\n","import { useEffect, RefObject } from 'react';\n\nexport const useClickOutside = <T extends HTMLElement>(\n\telementRef: RefObject<T>,\n\tcallback: () => void,\n): void => {\n\tuseEffect(() => {\n\t\tconst handleClickOutside = (event: MouseEvent): void => {\n\t\t\tif (\n\t\t\t\telementRef &&\n\t\t\t\telementRef.current &&\n\t\t\t\t!elementRef.current.contains(event.target as Node)\n\t\t\t) {\n\t\t\t\tcallback();\n\t\t\t}\n\t\t};\n\n\t\tdocument.addEventListener('click', handleClickOutside, true);\n\n\t\treturn () => {\n\t\t\tdocument.removeEventListener('click', handleClickOutside, true);\n\t\t};\n\t}, [elementRef, callback]);\n};\n"],"mappings":"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","names":["instance"]}
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AUTH_DOMAIN
|
|
3
|
+
} from "./chunk-MJBMK4OG.js";
|
|
4
|
+
import {
|
|
5
|
+
isNonEmptyString
|
|
6
|
+
} from "./chunk-SZMEZFAR.js";
|
|
7
|
+
|
|
8
|
+
// packages/utils/auth/auth.tsx
|
|
9
|
+
import React, { useState, useEffect, useContext, useCallback } from "react";
|
|
10
|
+
import { jwtDecode } from "jwt-decode";
|
|
11
|
+
import { jsx } from "react/jsx-runtime";
|
|
12
|
+
var AuthContext = React.createContext(
|
|
13
|
+
void 0
|
|
14
|
+
);
|
|
15
|
+
var useAuth = () => {
|
|
16
|
+
const context = useContext(AuthContext);
|
|
17
|
+
if (!context) {
|
|
18
|
+
throw new Error("useAuth must be used within an AuthProvider");
|
|
19
|
+
}
|
|
20
|
+
return context;
|
|
21
|
+
};
|
|
22
|
+
var CAYUSE_LOGOUT_URL = `https://${AUTH_DOMAIN}/logout`;
|
|
23
|
+
var CAYUSE_LOGIN_URL = `https://${AUTH_DOMAIN}/authorize`;
|
|
24
|
+
var ACCESS_TOKEN = "fk_accessToken";
|
|
25
|
+
var ACCESS_TOKEN_EXP = "fk_accessTokenExp";
|
|
26
|
+
function loginWithRedirect({ tenantId, isGuest }) {
|
|
27
|
+
const currentUrl = window.location.href;
|
|
28
|
+
const encodedUri = encodeURIComponent(currentUrl);
|
|
29
|
+
let url = `${CAYUSE_LOGIN_URL}?redirect_uri=${encodedUri}&response_type=TOKEN`;
|
|
30
|
+
if (isNonEmptyString(tenantId)) {
|
|
31
|
+
url += `&tenant_id=${tenantId}`;
|
|
32
|
+
}
|
|
33
|
+
if (isGuest) {
|
|
34
|
+
url += "&guest=true";
|
|
35
|
+
}
|
|
36
|
+
window.location.replace(url);
|
|
37
|
+
}
|
|
38
|
+
var AuthProvider = ({
|
|
39
|
+
children,
|
|
40
|
+
PRODUCT_KEY,
|
|
41
|
+
setCayuseHeader,
|
|
42
|
+
tokenRefreshUrl,
|
|
43
|
+
isGuest
|
|
44
|
+
}) => {
|
|
45
|
+
const [isAuthenticated, setIsAuthenticated] = useState(false);
|
|
46
|
+
const [loading, setLoading] = useState(true);
|
|
47
|
+
const [user, setUser] = useState(null);
|
|
48
|
+
const [accessToken, setAccessToken] = useState(null);
|
|
49
|
+
const [refreshingToken, setRefreshingToken] = useState(false);
|
|
50
|
+
const retrieveAccessTokenFromLocationHash = () => {
|
|
51
|
+
const { hash } = window.location;
|
|
52
|
+
if (hash) {
|
|
53
|
+
const tokens = hash.substring(1, hash.length).split("&");
|
|
54
|
+
for (const token of tokens) {
|
|
55
|
+
if (token) {
|
|
56
|
+
const [key, value] = token.split("=");
|
|
57
|
+
if (key === "access_token" && value) {
|
|
58
|
+
const newAccessToken = value;
|
|
59
|
+
localStorage.setItem(ACCESS_TOKEN, newAccessToken);
|
|
60
|
+
const decodedToken = jwtDecode(newAccessToken);
|
|
61
|
+
localStorage.setItem(ACCESS_TOKEN_EXP, decodedToken.exp.toString());
|
|
62
|
+
setAccessToken(newAccessToken);
|
|
63
|
+
setIsAuthenticated(true);
|
|
64
|
+
const url = new URL(window.location.href);
|
|
65
|
+
window.history.replaceState(
|
|
66
|
+
{},
|
|
67
|
+
document.title,
|
|
68
|
+
url.pathname + url.search
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
const isAccessTokenExpired = () => {
|
|
76
|
+
const accessTokenFromStorage = localStorage.getItem(ACCESS_TOKEN);
|
|
77
|
+
if (!accessTokenFromStorage) {
|
|
78
|
+
return true;
|
|
79
|
+
}
|
|
80
|
+
const accessTokenExpirationFromStorage = localStorage.getItem(ACCESS_TOKEN_EXP);
|
|
81
|
+
let timeUntilTokenExpires;
|
|
82
|
+
if (accessTokenExpirationFromStorage) {
|
|
83
|
+
timeUntilTokenExpires = parseInt(accessTokenExpirationFromStorage, 10) - Math.floor((/* @__PURE__ */ new Date()).getTime() / 1e3);
|
|
84
|
+
} else {
|
|
85
|
+
const decodedToken = jwtDecode(accessTokenFromStorage);
|
|
86
|
+
timeUntilTokenExpires = decodedToken.exp - Math.floor((/* @__PURE__ */ new Date()).getTime() / 1e3);
|
|
87
|
+
}
|
|
88
|
+
return timeUntilTokenExpires < 60;
|
|
89
|
+
};
|
|
90
|
+
const refreshTokenSilently = useCallback(async () => {
|
|
91
|
+
if (refreshingToken) return false;
|
|
92
|
+
try {
|
|
93
|
+
setRefreshingToken(true);
|
|
94
|
+
let refreshUrl = isNonEmptyString(tokenRefreshUrl) ? tokenRefreshUrl : `${window.location.protocol}//${window.location.host}/api/refresh-token`;
|
|
95
|
+
if (user?.tenantId) {
|
|
96
|
+
refreshUrl += `?tenant_id=${user.tenantId}`;
|
|
97
|
+
}
|
|
98
|
+
if (isGuest) {
|
|
99
|
+
refreshUrl += refreshUrl.includes("?") ? "&guest=true" : "?guest=true";
|
|
100
|
+
}
|
|
101
|
+
if (!refreshUrl) {
|
|
102
|
+
throw new Error("Refresh URL is undefined");
|
|
103
|
+
}
|
|
104
|
+
const response = await fetch(refreshUrl, {
|
|
105
|
+
method: "GET",
|
|
106
|
+
credentials: "include",
|
|
107
|
+
headers: {
|
|
108
|
+
"Content-Type": "application/json",
|
|
109
|
+
Authorization: `Bearer ${localStorage.getItem(ACCESS_TOKEN)}`
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
if (!response.ok) {
|
|
113
|
+
throw new Error("Token refresh failed");
|
|
114
|
+
}
|
|
115
|
+
const data = await response.json();
|
|
116
|
+
if (data.access_token) {
|
|
117
|
+
localStorage.setItem(ACCESS_TOKEN, data.access_token);
|
|
118
|
+
const decodedToken = jwtDecode(data.access_token);
|
|
119
|
+
localStorage.setItem(ACCESS_TOKEN_EXP, decodedToken.exp.toString());
|
|
120
|
+
setAccessToken(data.access_token);
|
|
121
|
+
setIsAuthenticated(true);
|
|
122
|
+
return true;
|
|
123
|
+
}
|
|
124
|
+
return false;
|
|
125
|
+
} catch (error) {
|
|
126
|
+
console.error("Error refreshing token:", error);
|
|
127
|
+
return false;
|
|
128
|
+
} finally {
|
|
129
|
+
setRefreshingToken(false);
|
|
130
|
+
}
|
|
131
|
+
}, [refreshingToken, tokenRefreshUrl, user, isGuest]);
|
|
132
|
+
useEffect(() => {
|
|
133
|
+
const initAuth = async () => {
|
|
134
|
+
if (window.location.hash.includes("access_token=")) {
|
|
135
|
+
retrieveAccessTokenFromLocationHash();
|
|
136
|
+
setLoading(false);
|
|
137
|
+
} else if (localStorage.getItem(ACCESS_TOKEN)) {
|
|
138
|
+
if (isAccessTokenExpired()) {
|
|
139
|
+
setIsAuthenticated(false);
|
|
140
|
+
setLoading(false);
|
|
141
|
+
} else {
|
|
142
|
+
const accessTokenFromStorage = localStorage.getItem(ACCESS_TOKEN);
|
|
143
|
+
setAccessToken(accessTokenFromStorage);
|
|
144
|
+
setIsAuthenticated(true);
|
|
145
|
+
setLoading(false);
|
|
146
|
+
}
|
|
147
|
+
} else {
|
|
148
|
+
setIsAuthenticated(false);
|
|
149
|
+
setLoading(false);
|
|
150
|
+
}
|
|
151
|
+
};
|
|
152
|
+
initAuth();
|
|
153
|
+
}, []);
|
|
154
|
+
useEffect(() => {
|
|
155
|
+
if (accessToken) {
|
|
156
|
+
const token = localStorage.getItem(ACCESS_TOKEN);
|
|
157
|
+
if (isNonEmptyString(token) && token === accessToken) {
|
|
158
|
+
const decodedUser = jwtDecode(token);
|
|
159
|
+
setIsAuthenticated(true);
|
|
160
|
+
setUser(decodedUser);
|
|
161
|
+
const host = window.location.origin;
|
|
162
|
+
setCayuseHeader({
|
|
163
|
+
product: PRODUCT_KEY,
|
|
164
|
+
host,
|
|
165
|
+
userId: decodedUser.username,
|
|
166
|
+
authenticationToken: token
|
|
167
|
+
});
|
|
168
|
+
} else if (user?.tenantId) {
|
|
169
|
+
loginWithRedirect({ tenantId: user.tenantId, isGuest });
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}, [accessToken, isGuest]);
|
|
173
|
+
useEffect(() => {
|
|
174
|
+
if (isAuthenticated) {
|
|
175
|
+
const interval = setInterval(async () => {
|
|
176
|
+
if (isAccessTokenExpired()) {
|
|
177
|
+
const refreshed = await refreshTokenSilently();
|
|
178
|
+
if (!refreshed) {
|
|
179
|
+
setAccessToken(null);
|
|
180
|
+
localStorage.removeItem(ACCESS_TOKEN);
|
|
181
|
+
localStorage.removeItem(ACCESS_TOKEN_EXP);
|
|
182
|
+
setIsAuthenticated(false);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}, 5e3);
|
|
186
|
+
return () => clearInterval(interval);
|
|
187
|
+
}
|
|
188
|
+
}, [isAuthenticated, refreshTokenSilently]);
|
|
189
|
+
const logout = useCallback((event) => {
|
|
190
|
+
if (event.detail === "/logout") {
|
|
191
|
+
setAccessToken(null);
|
|
192
|
+
localStorage.removeItem(ACCESS_TOKEN);
|
|
193
|
+
localStorage.removeItem(ACCESS_TOKEN_EXP);
|
|
194
|
+
window.location.href = CAYUSE_LOGOUT_URL;
|
|
195
|
+
}
|
|
196
|
+
}, []);
|
|
197
|
+
useEffect(() => {
|
|
198
|
+
window.addEventListener("navigationChange", logout);
|
|
199
|
+
return () => window.removeEventListener("navigationChange", logout);
|
|
200
|
+
}, [logout]);
|
|
201
|
+
const contextValue = {
|
|
202
|
+
isAuthenticated,
|
|
203
|
+
loading,
|
|
204
|
+
user,
|
|
205
|
+
loginWithRedirect: (params) => loginWithRedirect({
|
|
206
|
+
...params,
|
|
207
|
+
isGuest: params.isGuest || isGuest
|
|
208
|
+
}),
|
|
209
|
+
refreshToken: refreshTokenSilently
|
|
210
|
+
};
|
|
211
|
+
return /* @__PURE__ */ jsx(AuthContext.Provider, { value: contextValue, children });
|
|
212
|
+
};
|
|
213
|
+
var withAuth = (Component) => {
|
|
214
|
+
return (props) => /* @__PURE__ */ jsx(AuthContext.Consumer, { children: (context) => /* @__PURE__ */ jsx(Component, { ...props, context }) });
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
export {
|
|
218
|
+
AuthContext,
|
|
219
|
+
useAuth,
|
|
220
|
+
ACCESS_TOKEN,
|
|
221
|
+
loginWithRedirect,
|
|
222
|
+
AuthProvider,
|
|
223
|
+
withAuth
|
|
224
|
+
};
|
|
225
|
+
//# sourceMappingURL=chunk-XRUFEGUC.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../packages/utils/auth/auth.tsx"],"sourcesContent":["import React, { useState, useEffect, useContext, useCallback } from 'react';\nimport { jwtDecode } from 'jwt-decode';\nimport { isNonEmptyString } from '@/utils/type-checks';\nimport { AUTH_DOMAIN } from '@/globals/constants';\n\ninterface User {\n\tusername: string;\n\ttenantId?: string;\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\t[key: string]: any;\n}\n\ninterface AuthContextValue {\n\tisAuthenticated: boolean;\n\tloading: boolean;\n\tuser: User | null;\n\tloginWithRedirect: (params: LoginParams) => void;\n\trefreshToken: () => Promise<boolean>;\n}\n\ninterface LoginParams {\n\ttenantId?: string;\n\tisGuest?: boolean;\n}\n\ninterface CayuseHeader {\n\tproduct: string;\n\thost: string;\n\tuserId: string;\n\tauthenticationToken: string;\n}\n\ninterface AuthProviderProps {\n\tchildren: React.ReactNode;\n\tPRODUCT_KEY: string;\n\tsetCayuseHeader: (header: CayuseHeader) => void;\n\ttokenRefreshUrl?: string;\n\tisGuest?: boolean;\n}\n\nexport const AuthContext = React.createContext<AuthContextValue | undefined>(\n\tundefined,\n);\n\nexport const useAuth = () => {\n\tconst context = useContext(AuthContext);\n\tif (!context) {\n\t\tthrow new Error('useAuth must be used within an AuthProvider');\n\t}\n\treturn context;\n};\n\nconst CAYUSE_LOGOUT_URL = `https://${AUTH_DOMAIN}/logout` as const;\nconst CAYUSE_LOGIN_URL = `https://${AUTH_DOMAIN}/authorize` as const;\nexport const ACCESS_TOKEN = 'fk_accessToken' as const;\nconst ACCESS_TOKEN_EXP = 'fk_accessTokenExp' as const;\n\nexport function loginWithRedirect({ tenantId, isGuest }: LoginParams): void {\n\tconst currentUrl = window.location.href;\n\tconst encodedUri = encodeURIComponent(currentUrl);\n\tlet url = `${CAYUSE_LOGIN_URL}?redirect_uri=${encodedUri}&response_type=TOKEN`;\n\n\tif (isNonEmptyString(tenantId)) {\n\t\turl += `&tenant_id=${tenantId}`;\n\t}\n\n\tif (isGuest) {\n\t\turl += '&guest=true';\n\t}\n\n\twindow.location.replace(url);\n}\n\nexport const AuthProvider: React.FC<AuthProviderProps> = ({\n\tchildren,\n\tPRODUCT_KEY,\n\tsetCayuseHeader,\n\ttokenRefreshUrl,\n\tisGuest,\n}) => {\n\tconst [isAuthenticated, setIsAuthenticated] = useState<boolean>(false);\n\tconst [loading, setLoading] = useState<boolean>(true);\n\tconst [user, setUser] = useState<User | null>(null);\n\tconst [accessToken, setAccessToken] = useState<string | null>(null);\n\tconst [refreshingToken, setRefreshingToken] = useState<boolean>(false);\n\n\tconst retrieveAccessTokenFromLocationHash = (): void => {\n\t\tconst { hash } = window.location;\n\n\t\tif (hash) {\n\t\t\tconst tokens = hash.substring(1, hash.length).split('&');\n\t\t\tfor (const token of tokens) {\n\t\t\t\tif (token) {\n\t\t\t\t\tconst [key, value] = token.split('=');\n\t\t\t\t\tif (key === 'access_token' && value) {\n\t\t\t\t\t\tconst newAccessToken = value;\n\t\t\t\t\t\tlocalStorage.setItem(ACCESS_TOKEN, newAccessToken);\n\t\t\t\t\t\tconst decodedToken = jwtDecode<{ exp: number }>(newAccessToken);\n\t\t\t\t\t\tlocalStorage.setItem(ACCESS_TOKEN_EXP, decodedToken.exp.toString());\n\t\t\t\t\t\tsetAccessToken(newAccessToken);\n\t\t\t\t\t\tsetIsAuthenticated(true);\n\n\t\t\t\t\t\tconst url = new URL(window.location.href);\n\t\t\t\t\t\twindow.history.replaceState(\n\t\t\t\t\t\t\t{},\n\t\t\t\t\t\t\tdocument.title,\n\t\t\t\t\t\t\turl.pathname + url.search,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\tconst isAccessTokenExpired = (): boolean => {\n\t\tconst accessTokenFromStorage = localStorage.getItem(ACCESS_TOKEN);\n\n\t\tif (!accessTokenFromStorage) {\n\t\t\treturn true;\n\t\t}\n\n\t\tconst accessTokenExpirationFromStorage = localStorage.getItem(ACCESS_TOKEN_EXP);\n\t\tlet timeUntilTokenExpires: number;\n\n\t\tif (accessTokenExpirationFromStorage) {\n\t\t\ttimeUntilTokenExpires =\n\t\t\t\tparseInt(accessTokenExpirationFromStorage, 10) -\n\t\t\t\tMath.floor(new Date().getTime() / 1000);\n\t\t} else {\n\t\t\tconst decodedToken = jwtDecode<{ exp: number }>(accessTokenFromStorage);\n\t\t\ttimeUntilTokenExpires =\n\t\t\t\tdecodedToken.exp - Math.floor(new Date().getTime() / 1000);\n\t\t}\n\n\t\treturn timeUntilTokenExpires < 60;\n\t};\n\n\tconst refreshTokenSilently = useCallback(async (): Promise<boolean> => {\n\t\tif (refreshingToken) return false;\n\n\t\ttry {\n\t\t\tsetRefreshingToken(true);\n\n\t\t\tlet refreshUrl = isNonEmptyString(tokenRefreshUrl)\n\t\t\t\t? tokenRefreshUrl!\n\t\t\t\t: `${window.location.protocol}//${window.location.host}/api/refresh-token`;\n\n\t\t\tif (user?.tenantId) {\n\t\t\t\trefreshUrl += `?tenant_id=${user.tenantId}`;\n\t\t\t}\n\n\t\t\tif (isGuest) {\n\t\t\t\trefreshUrl += refreshUrl.includes('?') ? '&guest=true' : '?guest=true';\n\t\t\t}\n\n\t\t\tif (!refreshUrl) {\n\t\t\t\tthrow new Error('Refresh URL is undefined');\n\t\t\t}\n\n\t\t\tconst response = await fetch(refreshUrl, {\n\t\t\t\tmethod: 'GET',\n\t\t\t\tcredentials: 'include',\n\t\t\t\theaders: {\n\t\t\t\t\t'Content-Type': 'application/json',\n\t\t\t\t\tAuthorization: `Bearer ${localStorage.getItem(ACCESS_TOKEN)}`,\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tif (!response.ok) {\n\t\t\t\tthrow new Error('Token refresh failed');\n\t\t\t}\n\n\t\t\tconst data: { access_token?: string } = await response.json();\n\n\t\t\tif (data.access_token) {\n\t\t\t\tlocalStorage.setItem(ACCESS_TOKEN, data.access_token);\n\t\t\t\tconst decodedToken = jwtDecode<{ exp: number }>(data.access_token);\n\t\t\t\tlocalStorage.setItem(ACCESS_TOKEN_EXP, decodedToken.exp.toString());\n\t\t\t\tsetAccessToken(data.access_token);\n\t\t\t\tsetIsAuthenticated(true);\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\treturn false;\n\t\t} catch (error) {\n\t\t\tconsole.error('Error refreshing token:', error);\n\t\t\treturn false;\n\t\t} finally {\n\t\t\tsetRefreshingToken(false);\n\t\t}\n\t}, [refreshingToken, tokenRefreshUrl, user, isGuest]);\n\n\tuseEffect(() => {\n\t\tconst initAuth = async (): Promise<void> => {\n\t\t\tif (window.location.hash.includes('access_token=')) {\n\t\t\t\tretrieveAccessTokenFromLocationHash();\n\t\t\t\tsetLoading(false);\n\t\t\t} else if (localStorage.getItem(ACCESS_TOKEN)) {\n\t\t\t\tif (isAccessTokenExpired()) {\n\t\t\t\t\tsetIsAuthenticated(false);\n\t\t\t\t\tsetLoading(false);\n\t\t\t\t} else {\n\t\t\t\t\tconst accessTokenFromStorage = localStorage.getItem(ACCESS_TOKEN)!;\n\t\t\t\t\tsetAccessToken(accessTokenFromStorage);\n\t\t\t\t\tsetIsAuthenticated(true);\n\t\t\t\t\tsetLoading(false);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tsetIsAuthenticated(false);\n\t\t\t\tsetLoading(false);\n\t\t\t}\n\t\t};\n\n\t\tinitAuth();\n\t}, []);\n\n\tuseEffect(() => {\n\t\tif (accessToken) {\n\t\t\tconst token = localStorage.getItem(ACCESS_TOKEN);\n\t\t\tif (isNonEmptyString(token) && token === accessToken) {\n\t\t\t\tconst decodedUser = jwtDecode<User>(token);\n\t\t\t\tsetIsAuthenticated(true);\n\t\t\t\tsetUser(decodedUser);\n\n\t\t\t\tconst host = window.location.origin;\n\t\t\t\tsetCayuseHeader({\n\t\t\t\t\tproduct: PRODUCT_KEY,\n\t\t\t\t\thost,\n\t\t\t\t\tuserId: decodedUser.username,\n\t\t\t\t\tauthenticationToken: token,\n\t\t\t\t});\n\t\t\t} else if (user?.tenantId) {\n\t\t\t\tloginWithRedirect({ tenantId: user.tenantId, isGuest });\n\t\t\t}\n\t\t}\n\t\t// eslint-disable-next-line react-hooks/exhaustive-deps\n\t}, [accessToken, isGuest]);\n\n\tuseEffect(() => {\n\t\tif (isAuthenticated) {\n\t\t\tconst interval = setInterval(async () => {\n\t\t\t\tif (isAccessTokenExpired()) {\n\t\t\t\t\tconst refreshed = await refreshTokenSilently();\n\t\t\t\t\tif (!refreshed) {\n\t\t\t\t\t\tsetAccessToken(null);\n\t\t\t\t\t\tlocalStorage.removeItem(ACCESS_TOKEN);\n\t\t\t\t\t\tlocalStorage.removeItem(ACCESS_TOKEN_EXP);\n\t\t\t\t\t\tsetIsAuthenticated(false);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}, 5_000);\n\n\t\t\treturn () => clearInterval(interval);\n\t\t}\n\t}, [isAuthenticated, refreshTokenSilently]);\n\n\tconst logout = useCallback((event: CustomEvent): void => {\n\t\tif (event.detail === '/logout') {\n\t\t\tsetAccessToken(null);\n\t\t\tlocalStorage.removeItem(ACCESS_TOKEN);\n\t\t\tlocalStorage.removeItem(ACCESS_TOKEN_EXP);\n\t\t\twindow.location.href = CAYUSE_LOGOUT_URL;\n\t\t}\n\t}, []) as EventListener;\n\n\tuseEffect(() => {\n\t\twindow.addEventListener('navigationChange', logout);\n\n\t\treturn () => window.removeEventListener('navigationChange', logout);\n\t}, [logout]);\n\n\t// Context value with proper typing\n\tconst contextValue: AuthContextValue = {\n\t\tisAuthenticated,\n\t\tloading,\n\t\tuser,\n\t\tloginWithRedirect: (params: LoginParams) =>\n\t\t\tloginWithRedirect({\n\t\t\t\t...params,\n\t\t\t\tisGuest: params.isGuest || isGuest,\n\t\t\t}),\n\t\trefreshToken: refreshTokenSilently,\n\t};\n\n\treturn (\n\t\t<AuthContext.Provider value={contextValue}>{children}</AuthContext.Provider>\n\t);\n};\n\nexport const withAuth = <P extends object>(\n\tComponent: React.ComponentType<P & { context: AuthContextValue }>,\n) => {\n\treturn (props: P) => (\n\t\t<AuthContext.Consumer>\n\t\t\t{(context) => <Component {...props} context={context!} />}\n\t\t</AuthContext.Consumer>\n\t);\n};\n"],"mappings":"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","names":[]}
|