@amp-labs/react 1.5.0 → 1.5.2
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/build/src/components/Configure/content/fields/OptionalFields/OptionalFields.js +21 -9
- package/build/src/components/Configure/content/fields/RequiredFields.js +1 -1
- package/build/src/components/Configure/layout/ConditionalProxyLayout/ConditionalProxyLayout.js +2 -1
- package/build/src/components/Oauth/NoWorkspaceEntry/NoWorkspaceOauthFlow.js +8 -11
- package/build/src/components/Oauth/OAuthWindow/OAuthWindow.d.ts +14 -0
- package/build/src/components/Oauth/OAuthWindow/OAuthWindow.js +65 -0
- package/build/src/components/Oauth/OAuthWindow/windowHelpers.d.ts +24 -0
- package/build/src/components/Oauth/OAuthWindow/windowHelpers.js +77 -0
- package/build/src/components/Oauth/WorkspaceEntry/WorkspaceOauthFlow.js +4 -7
- package/build/src/components/Oauth/fetchOAuthPopupURL.d.ts +1 -0
- package/build/src/components/Oauth/{fetchOAuthCallbackURL.js → fetchOAuthPopupURL.js} +7 -6
- package/build/src/services/api.d.ts +2 -2
- package/build/src/services/version.d.ts +1 -1
- package/build/src/services/version.js +1 -1
- package/package.json +4 -4
- package/build/src/components/Oauth/OAuthPopup.d.ts +0 -14
- package/build/src/components/Oauth/OAuthPopup.js +0 -79
- package/build/src/components/Oauth/fetchOAuthCallbackURL.d.ts +0 -1
|
@@ -8,7 +8,7 @@ const useSelectedConfigureState_1 = require("../../useSelectedConfigureState");
|
|
|
8
8
|
const FieldHeader_1 = require("../FieldHeader");
|
|
9
9
|
const setOptionalField_1 = require("./setOptionalField");
|
|
10
10
|
function OptionalFields() {
|
|
11
|
-
var _a, _b
|
|
11
|
+
var _a, _b;
|
|
12
12
|
const { appName, configureState, setConfigureState, selectedObjectName, } = (0, useSelectedConfigureState_1.useSelectedConfigureState)();
|
|
13
13
|
const selectedOptionalFields = (_a = configureState === null || configureState === void 0 ? void 0 : configureState.read) === null || _a === void 0 ? void 0 : _a.selectedOptionalFields;
|
|
14
14
|
const onCheckboxChange = (e) => {
|
|
@@ -17,13 +17,25 @@ function OptionalFields() {
|
|
|
17
17
|
(0, setOptionalField_1.setOptionalField)(selectedObjectName, setConfigureState, name, checked);
|
|
18
18
|
}
|
|
19
19
|
};
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
}
|
|
20
|
+
const readOptionalFields = (_b = configureState === null || configureState === void 0 ? void 0 : configureState.read) === null || _b === void 0 ? void 0 : _b.optionalFields;
|
|
21
|
+
const onSelectAllCheckboxChange = (e) => {
|
|
22
|
+
const { checked } = e.target;
|
|
23
|
+
if (selectedObjectName && readOptionalFields) {
|
|
24
|
+
readOptionalFields.forEach((field) => {
|
|
25
|
+
if (!(0, utils_1.isIntegrationFieldMapping)(field)) {
|
|
26
|
+
(0, setOptionalField_1.setOptionalField)(selectedObjectName, setConfigureState, field.fieldName, checked);
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
const shouldRender = !!(readOptionalFields && readOptionalFields.length > 0);
|
|
32
|
+
const isAllChecked = Object.keys(selectedOptionalFields || {}).length === (readOptionalFields === null || readOptionalFields === void 0 ? void 0 : readOptionalFields.length);
|
|
33
|
+
const isIndeterminate = !isAllChecked && Object.keys(selectedOptionalFields || {}).length > 0;
|
|
34
|
+
return (shouldRender && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(FieldHeader_1.FieldHeader, { string: `${appName} reads the following optional fields` }), (0, jsx_runtime_1.jsxs)(react_1.Stack, { marginBottom: 10, maxHeight: 300, overflowY: "scroll", border: "2px solid #EFEFEF", borderRadius: 8, gap: 0, children: [((readOptionalFields === null || readOptionalFields === void 0 ? void 0 : readOptionalFields.length) || 0) >= 2 && ((0, jsx_runtime_1.jsx)(react_1.Box, { backgroundColor: "gray.50", paddingX: 4, paddingY: 2, children: (0, jsx_runtime_1.jsx)(react_1.Checkbox, { name: "selectAll", id: "selectAll", onChange: onSelectAllCheckboxChange, isIndeterminate: isIndeterminate, isChecked: isAllChecked, children: "Select all" }) })), readOptionalFields.map((field) => {
|
|
35
|
+
if (!(0, utils_1.isIntegrationFieldMapping)(field)) {
|
|
36
|
+
return ((0, jsx_runtime_1.jsx)(react_1.Box, { paddingX: 4, paddingY: 2, borderBottom: "1px", borderColor: "gray.100", children: (0, jsx_runtime_1.jsx)(react_1.Checkbox, { name: field.fieldName, id: field.fieldName, isChecked: !!(selectedOptionalFields === null || selectedOptionalFields === void 0 ? void 0 : selectedOptionalFields[field === null || field === void 0 ? void 0 : field.fieldName]), onChange: onCheckboxChange, children: field.displayName }) }, field.fieldName));
|
|
37
|
+
}
|
|
38
|
+
return null; // fallback for customed mapped fields
|
|
39
|
+
})] })] })));
|
|
28
40
|
}
|
|
29
41
|
exports.OptionalFields = OptionalFields;
|
|
@@ -11,7 +11,7 @@ function RequiredFields() {
|
|
|
11
11
|
var _a, _b, _c;
|
|
12
12
|
const { configureState, selectedObjectName } = (0, useSelectedConfigureState_1.useSelectedConfigureState)();
|
|
13
13
|
const { appName } = (0, ProjectContextProvider_1.useProject)();
|
|
14
|
-
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(FieldHeader_1.FieldHeader, { string: `${appName} reads the following ${selectedObjectName} fields` }), (0, jsx_runtime_1.jsx)(react_1.Box, { marginBottom: "20px", children: ((_b = (_a = configureState === null || configureState === void 0 ? void 0 : configureState.read) === null || _a === void 0 ? void 0 : _a.requiredFields) === null || _b === void 0 ? void 0 : _b.length)
|
|
14
|
+
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(FieldHeader_1.FieldHeader, { string: `${appName} reads the following ${selectedObjectName} fields` }), (0, jsx_runtime_1.jsx)(react_1.Box, { marginBottom: "20px", display: "flex", gap: 1, children: ((_b = (_a = configureState === null || configureState === void 0 ? void 0 : configureState.read) === null || _a === void 0 ? void 0 : _a.requiredFields) === null || _b === void 0 ? void 0 : _b.length)
|
|
15
15
|
? ((_c = configureState.read) === null || _c === void 0 ? void 0 : _c.requiredFields.map((field) => {
|
|
16
16
|
if (!(0, utils_1.isIntegrationFieldMapping)(field)) {
|
|
17
17
|
return (0, jsx_runtime_1.jsx)(react_1.Tag, { children: field.displayName }, field.fieldName);
|
package/build/src/components/Configure/layout/ConditionalProxyLayout/ConditionalProxyLayout.js
CHANGED
|
@@ -36,7 +36,8 @@ function ConditionalProxyLayout({ children }) {
|
|
|
36
36
|
const provider = (_a = hydratedRevision === null || hydratedRevision === void 0 ? void 0 : hydratedRevision.content) === null || _a === void 0 ? void 0 : _a.provider;
|
|
37
37
|
const isProxyOnly = getIsProxyOnly(hydratedRevision);
|
|
38
38
|
(0, react_1.useEffect)(() => {
|
|
39
|
-
if (!isLoading && hydratedRevision && isProxyOnly
|
|
39
|
+
if (!isLoading && hydratedRevision && isProxyOnly
|
|
40
|
+
&& !installation && selectedConnection && apiKey && (integrationObj === null || integrationObj === void 0 ? void 0 : integrationObj.id)) {
|
|
40
41
|
setCreateInstallLoading(true);
|
|
41
42
|
(0, onCreateInstallationProxyOnly_1.onCreateInstallationProxyOnly)({
|
|
42
43
|
apiKey,
|
|
@@ -1,7 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
3
|
exports.NoWorkspaceOauthFlow = void 0;
|
|
7
4
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
@@ -12,8 +9,8 @@ const react_1 = require("react");
|
|
|
12
9
|
const ApiKeyContextProvider_1 = require("../../../context/ApiKeyContextProvider");
|
|
13
10
|
const ProjectContextProvider_1 = require("../../../context/ProjectContextProvider");
|
|
14
11
|
const utils_1 = require("../../../utils");
|
|
15
|
-
const
|
|
16
|
-
const
|
|
12
|
+
const fetchOAuthPopupURL_1 = require("../fetchOAuthPopupURL");
|
|
13
|
+
const OAuthWindow_1 = require("../OAuthWindow/OAuthWindow");
|
|
17
14
|
const LandingContent_1 = require("./LandingContent");
|
|
18
15
|
/**
|
|
19
16
|
* NoWorkspaceOauthFlow first prompts user with a next button,
|
|
@@ -22,25 +19,25 @@ const LandingContent_1 = require("./LandingContent");
|
|
|
22
19
|
function NoWorkspaceOauthFlow({ provider, consumerRef, consumerName, groupRef, groupName, }) {
|
|
23
20
|
const { projectId } = (0, ProjectContextProvider_1.useProject)();
|
|
24
21
|
const apiKey = (0, ApiKeyContextProvider_1.useApiKey)();
|
|
25
|
-
const [
|
|
22
|
+
const [oAuthPopupURL, setOAuthPopupURL] = (0, react_1.useState)(null);
|
|
26
23
|
const [error, setError] = (0, react_1.useState)(null);
|
|
27
24
|
// fetch OAuth callback URL from connection so that oath popup can be launched
|
|
28
25
|
const handleSubmit = async () => {
|
|
29
26
|
var _a;
|
|
30
27
|
setError(null);
|
|
31
28
|
try {
|
|
32
|
-
const url = await (0,
|
|
33
|
-
|
|
29
|
+
const url = await (0, fetchOAuthPopupURL_1.fetchOAuthPopupURL)(projectId, consumerRef, groupRef, apiKey, provider, undefined, consumerName, groupName);
|
|
30
|
+
setOAuthPopupURL(url);
|
|
34
31
|
}
|
|
35
32
|
catch (err) {
|
|
36
|
-
console.error(err);
|
|
33
|
+
console.error('Could not fetch OAuth popup URL', { err });
|
|
37
34
|
setError((_a = err.message) !== null && _a !== void 0 ? _a : 'Unexpected error');
|
|
38
35
|
}
|
|
39
36
|
};
|
|
40
37
|
const onClose = (0, react_1.useCallback)((err) => {
|
|
41
38
|
setError(err);
|
|
42
|
-
|
|
39
|
+
setOAuthPopupURL(null);
|
|
43
40
|
}, []);
|
|
44
|
-
return ((0, jsx_runtime_1.jsx)(
|
|
41
|
+
return ((0, jsx_runtime_1.jsx)(OAuthWindow_1.OAuthWindow, { windowTitle: `Connect to ${(0, utils_1.capitalize)(provider)}`, oauthUrl: oAuthPopupURL, onClose: onClose, children: (0, jsx_runtime_1.jsx)(LandingContent_1.LandingContent, { provider: provider, handleSubmit: handleSubmit, error: error }) }));
|
|
45
42
|
}
|
|
46
43
|
exports.NoWorkspaceOauthFlow = NoWorkspaceOauthFlow;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
type OAuthWindowProps = {
|
|
3
|
+
children: React.ReactNode;
|
|
4
|
+
windowTitle: string;
|
|
5
|
+
oauthUrl: string | null;
|
|
6
|
+
onClose: (err: string | null) => void;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* v2 OAuth window to manage OAuth flow
|
|
10
|
+
* @param param0
|
|
11
|
+
* @returns
|
|
12
|
+
*/
|
|
13
|
+
export declare function OAuthWindow({ children, oauthUrl, windowTitle, onClose, }: OAuthWindowProps): import("react/jsx-runtime").JSX.Element;
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.OAuthWindow = void 0;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const react_1 = require("react");
|
|
6
|
+
const ApiKeyContextProvider_1 = require("../../../context/ApiKeyContextProvider");
|
|
7
|
+
const ConnectionsContextProvider_1 = require("../../../context/ConnectionsContextProvider");
|
|
8
|
+
const ProjectContextProvider_1 = require("../../../context/ProjectContextProvider");
|
|
9
|
+
const windowHelpers_1 = require("./windowHelpers");
|
|
10
|
+
/**
|
|
11
|
+
* v2 OAuth window to manage OAuth flow
|
|
12
|
+
* @param param0
|
|
13
|
+
* @returns
|
|
14
|
+
*/
|
|
15
|
+
function OAuthWindow({ children, oauthUrl, windowTitle = 'Connect to Provider', onClose, }) {
|
|
16
|
+
const apiKey = (0, ApiKeyContextProvider_1.useApiKey)();
|
|
17
|
+
const { projectId } = (0, ProjectContextProvider_1.useProject)();
|
|
18
|
+
const [connectionId, setConnectionId] = (0, react_1.useState)(null);
|
|
19
|
+
const [oauthWindow, setOauthWindow] = (0, react_1.useState)(null);
|
|
20
|
+
const { setSelectedConnection } = (0, ConnectionsContextProvider_1.useConnections)();
|
|
21
|
+
const receiveMessage = (0, windowHelpers_1.getReceiveMessageEventHandler)(setConnectionId);
|
|
22
|
+
const openOAuthWindow = (0, windowHelpers_1.getOpenWindowHandler)(windowTitle, setOauthWindow, receiveMessage, oauthUrl);
|
|
23
|
+
const refreshConnections = (0, windowHelpers_1.getRefreshConnectionHandler)(projectId, apiKey, setSelectedConnection);
|
|
24
|
+
// open the OAuth window on mount and prop change
|
|
25
|
+
(0, react_1.useEffect)(() => {
|
|
26
|
+
if (oauthUrl && !oauthWindow) {
|
|
27
|
+
openOAuthWindow(); // creates new window and adds event listener
|
|
28
|
+
}
|
|
29
|
+
}, [oauthUrl, oauthWindow, openOAuthWindow, receiveMessage, windowTitle]);
|
|
30
|
+
// refresh connections on connectionId change
|
|
31
|
+
(0, react_1.useEffect)(() => {
|
|
32
|
+
if (connectionId) {
|
|
33
|
+
refreshConnections(connectionId)
|
|
34
|
+
.then(() => {
|
|
35
|
+
oauthWindow === null || oauthWindow === void 0 ? void 0 : oauthWindow.close(); // only close the window if connection is successful
|
|
36
|
+
// console.debug('Connection successful');
|
|
37
|
+
}).catch((err) => {
|
|
38
|
+
var _a;
|
|
39
|
+
console.error('Error refreshing connection: ', err);
|
|
40
|
+
onClose((_a = err.message) !== null && _a !== void 0 ? _a : 'Unexpected error: not able to refresh connection');
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
}, [connectionId, apiKey, setSelectedConnection, refreshConnections, oauthWindow, onClose]);
|
|
44
|
+
// check if the window is closed
|
|
45
|
+
const interval = oauthWindow && setInterval(() => {
|
|
46
|
+
if (((oauthWindow === null || oauthWindow === void 0 ? void 0 : oauthWindow.closed) || !oauthWindow) && !!interval) {
|
|
47
|
+
clearInterval(interval);
|
|
48
|
+
// cleanup event listener and window reference
|
|
49
|
+
window.removeEventListener('message', receiveMessage);
|
|
50
|
+
setOauthWindow(null);
|
|
51
|
+
if (!connectionId) {
|
|
52
|
+
// if connectionId is not set, then set OAuth failed error
|
|
53
|
+
console.error('OAuth failed. Please try again.');
|
|
54
|
+
if (onClose)
|
|
55
|
+
onClose('OAuth failed. Please try again.');
|
|
56
|
+
}
|
|
57
|
+
else if (connectionId && onClose) {
|
|
58
|
+
// if connectionId is set, then set OAuth success -- no error in onClose
|
|
59
|
+
onClose(null);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}, 500);
|
|
63
|
+
return (0, jsx_runtime_1.jsx)("div", { children: children });
|
|
64
|
+
}
|
|
65
|
+
exports.OAuthWindow = OAuthWindow;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import { Connection } from '../../../services/api';
|
|
3
|
+
/**
|
|
4
|
+
* returns a function to refresh the connection
|
|
5
|
+
* @param projectId
|
|
6
|
+
* @param apiKey
|
|
7
|
+
* @param setSelectedConnection
|
|
8
|
+
* @returns
|
|
9
|
+
*/
|
|
10
|
+
export declare function getRefreshConnectionHandler(projectId: string, apiKey: string, setSelectedConnection: React.Dispatch<React.SetStateAction<Connection | null>>): (_connectionId: string) => Promise<void>;
|
|
11
|
+
/**
|
|
12
|
+
* opens a new window with the OAuth URL
|
|
13
|
+
* side effect: adds a message event listener to the window
|
|
14
|
+
* @param oauthUrl
|
|
15
|
+
* @param windowTitle
|
|
16
|
+
* @param setOauthWindow
|
|
17
|
+
* @param receiveMessage
|
|
18
|
+
* @returns a function to open the oauth window
|
|
19
|
+
*/
|
|
20
|
+
export declare function getOpenWindowHandler(windowTitle: string, setOauthWindow: React.Dispatch<React.SetStateAction<Window | null>>, receiveMessage: (event: MessageEvent) => void, oauthUrl: string | null): () => void;
|
|
21
|
+
/**
|
|
22
|
+
* returns a function to handle the message event
|
|
23
|
+
*/
|
|
24
|
+
export declare function getReceiveMessageEventHandler(setConnectionId: React.Dispatch<React.SetStateAction<null>>): (event: MessageEvent) => void;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getReceiveMessageEventHandler = exports.getOpenWindowHandler = exports.getRefreshConnectionHandler = void 0;
|
|
4
|
+
const react_1 = require("react");
|
|
5
|
+
const api_1 = require("../../../services/api");
|
|
6
|
+
const DEFAULT_WIDTH = 600; // px
|
|
7
|
+
const DEFAULT_HEIGHT = 600; // px
|
|
8
|
+
const SUCCESS_EVENT = 'AUTHORIZATION_SUCCEEDED';
|
|
9
|
+
const FAILURE_EVENT = 'AUTHORIZATION_FAILED';
|
|
10
|
+
/**
|
|
11
|
+
* returns a function to refresh the connection
|
|
12
|
+
* @param projectId
|
|
13
|
+
* @param apiKey
|
|
14
|
+
* @param setSelectedConnection
|
|
15
|
+
* @returns
|
|
16
|
+
*/
|
|
17
|
+
function getRefreshConnectionHandler(projectId, apiKey, setSelectedConnection) {
|
|
18
|
+
return (0, react_1.useCallback)(async (_connectionId) => {
|
|
19
|
+
const connection = await (0, api_1.api)().connectionApi.getConnection({ projectId, connectionId: _connectionId }, {
|
|
20
|
+
headers: { 'X-Api-Key': apiKey !== null && apiKey !== void 0 ? apiKey : '' },
|
|
21
|
+
});
|
|
22
|
+
setSelectedConnection(connection);
|
|
23
|
+
}, [projectId, apiKey, setSelectedConnection]);
|
|
24
|
+
}
|
|
25
|
+
exports.getRefreshConnectionHandler = getRefreshConnectionHandler;
|
|
26
|
+
/**
|
|
27
|
+
* opens a new window with the OAuth URL
|
|
28
|
+
* side effect: adds a message event listener to the window
|
|
29
|
+
* @param oauthUrl
|
|
30
|
+
* @param windowTitle
|
|
31
|
+
* @param setOauthWindow
|
|
32
|
+
* @param receiveMessage
|
|
33
|
+
* @returns a function to open the oauth window
|
|
34
|
+
*/
|
|
35
|
+
function getOpenWindowHandler(windowTitle, setOauthWindow, receiveMessage, oauthUrl) {
|
|
36
|
+
return (0, react_1.useCallback)(() => {
|
|
37
|
+
if (!oauthUrl)
|
|
38
|
+
return;
|
|
39
|
+
const left = window.screenX + (window.outerWidth - DEFAULT_WIDTH) / 2;
|
|
40
|
+
const top = window.screenY + (window.outerHeight - DEFAULT_HEIGHT) / 2.5;
|
|
41
|
+
const windowDimensions = `width=${DEFAULT_WIDTH},height=${DEFAULT_HEIGHT},left=${left},top=${top}`;
|
|
42
|
+
// creates a new window
|
|
43
|
+
const newWindow = window.open(oauthUrl, windowTitle, windowDimensions);
|
|
44
|
+
setOauthWindow(newWindow);
|
|
45
|
+
window.addEventListener('message', receiveMessage, false);
|
|
46
|
+
}, [oauthUrl, windowTitle, setOauthWindow, receiveMessage]);
|
|
47
|
+
}
|
|
48
|
+
exports.getOpenWindowHandler = getOpenWindowHandler;
|
|
49
|
+
/**
|
|
50
|
+
* returns a function to handle the message event
|
|
51
|
+
*/
|
|
52
|
+
function getReceiveMessageEventHandler(setConnectionId) {
|
|
53
|
+
return (0, react_1.useCallback)((event) => {
|
|
54
|
+
var _a;
|
|
55
|
+
// Ignore messages from unexpected origins
|
|
56
|
+
if (event.origin !== api_1.AMP_SERVER) {
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
// success case
|
|
60
|
+
if (event.data.eventType === SUCCESS_EVENT) {
|
|
61
|
+
const connection = (_a = event.data.data) === null || _a === void 0 ? void 0 : _a.connection; // connection id
|
|
62
|
+
if (connection) {
|
|
63
|
+
setConnectionId(connection);
|
|
64
|
+
// do not close the window if connection is successful yet
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
console.error('Connection ID not found in event data: ', { event });
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
// failure case
|
|
71
|
+
if (event.data.eventType === FAILURE_EVENT) {
|
|
72
|
+
console.error('OAuth failed: ', { event });
|
|
73
|
+
// do not close the window if error occurs
|
|
74
|
+
}
|
|
75
|
+
}, [setConnectionId]);
|
|
76
|
+
}
|
|
77
|
+
exports.getReceiveMessageEventHandler = getReceiveMessageEventHandler;
|
|
@@ -1,7 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
3
|
exports.WorkspaceOauthFlow = void 0;
|
|
7
4
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
@@ -9,8 +6,8 @@ const react_1 = require("react");
|
|
|
9
6
|
const ApiKeyContextProvider_1 = require("../../../context/ApiKeyContextProvider");
|
|
10
7
|
const ProjectContextProvider_1 = require("../../../context/ProjectContextProvider");
|
|
11
8
|
const utils_1 = require("../../../utils");
|
|
12
|
-
const
|
|
13
|
-
const
|
|
9
|
+
const fetchOAuthPopupURL_1 = require("../fetchOAuthPopupURL");
|
|
10
|
+
const OAuthWindow_1 = require("../OAuthWindow/OAuthWindow");
|
|
14
11
|
const SalesforceSubdomainEntry_1 = require("../Salesforce/SalesforceSubdomainEntry");
|
|
15
12
|
const WorkspaceEntry_1 = require("./WorkspaceEntry");
|
|
16
13
|
const PROVIDER_SALESFORCE = 'salesforce';
|
|
@@ -34,7 +31,7 @@ function WorkspaceOauthFlow({ provider, consumerRef, consumerName, groupRef, gro
|
|
|
34
31
|
return;
|
|
35
32
|
}
|
|
36
33
|
try {
|
|
37
|
-
const url = await (0,
|
|
34
|
+
const url = await (0, fetchOAuthPopupURL_1.fetchOAuthPopupURL)(projectId, consumerRef, groupRef, apiKey, provider, workspace, consumerName, groupName);
|
|
38
35
|
setOAuthCallbackURL(url);
|
|
39
36
|
}
|
|
40
37
|
catch (err) {
|
|
@@ -51,6 +48,6 @@ function WorkspaceOauthFlow({ provider, consumerRef, consumerName, groupRef, gro
|
|
|
51
48
|
? ((0, jsx_runtime_1.jsx)(SalesforceSubdomainEntry_1.SalesforceSubdomainEntry, { handleSubmit: handleSubmit, setWorkspace: setWorkspace, error: error, isButtonDisabled: workspace.length === 0 })) : (
|
|
52
49
|
// general workspace entry component
|
|
53
50
|
(0, jsx_runtime_1.jsx)(WorkspaceEntry_1.WorkspaceEntry, { provider: provider, handleSubmit: handleSubmit, setWorkspace: setWorkspace, error: error, isButtonDisabled: workspace.length === 0 }));
|
|
54
|
-
return ((0, jsx_runtime_1.jsx)(
|
|
51
|
+
return ((0, jsx_runtime_1.jsx)(OAuthWindow_1.OAuthWindow, { windowTitle: `Connect to ${(0, utils_1.capitalize)(provider)}`, oauthUrl: oAuthCallbackURL, onClose: onClose, children: workspaceEntryComponent }));
|
|
55
52
|
}
|
|
56
53
|
exports.WorkspaceOauthFlow = WorkspaceOauthFlow;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const fetchOAuthPopupURL: (projectId: string, consumerRef: string, groupRef: string, apiKey: string, provider: string, workspace?: string, consumerName?: string, groupName?: string) => Promise<string>;
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.fetchOAuthPopupURL = void 0;
|
|
4
4
|
const api_1 = require("../../services/api");
|
|
5
5
|
const utils_1 = require("../../utils");
|
|
6
|
-
const
|
|
6
|
+
const fetchOAuthPopupURL = async (projectId, consumerRef, groupRef, apiKey, provider, workspace, consumerName, groupName) => {
|
|
7
7
|
const providerApps = await (0, api_1.api)().providerAppApi.listProviderApps({ projectId }, {
|
|
8
8
|
headers: { 'X-Api-Key': apiKey !== null && apiKey !== void 0 ? apiKey : '' },
|
|
9
9
|
});
|
|
10
10
|
const app = providerApps.find((a) => a.provider === provider);
|
|
11
11
|
if (!app) {
|
|
12
|
-
throw new Error(`You must first set up a ${(0, utils_1.capitalize)(provider)}
|
|
12
|
+
throw new Error(`You must first set up a ${(0, utils_1.capitalize)(provider)} Provider App using the Ampersand Console.`);
|
|
13
13
|
}
|
|
14
|
-
const
|
|
14
|
+
const request = {
|
|
15
15
|
connectOAuthParams: {
|
|
16
16
|
providerWorkspaceRef: workspace,
|
|
17
17
|
projectId,
|
|
@@ -22,7 +22,8 @@ const fetchOAuthCallbackURL = async (projectId, consumerRef, groupRef, apiKey, p
|
|
|
22
22
|
providerAppId: app.id,
|
|
23
23
|
provider,
|
|
24
24
|
},
|
|
25
|
-
}
|
|
25
|
+
};
|
|
26
|
+
const url = await (0, api_1.api)().oAuthApi.oauthConnect(request);
|
|
26
27
|
return url;
|
|
27
28
|
};
|
|
28
|
-
exports.
|
|
29
|
+
exports.fetchOAuthPopupURL = fetchOAuthPopupURL;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Config, Connection, CreateInstallationOperationRequest, CreateInstallationRequestConfig, HydratedIntegrationField, HydratedIntegrationFieldExistent, HydratedIntegrationObject, HydratedIntegrationRead, HydratedIntegrationWrite, HydratedIntegrationWriteObject, HydratedRevision, Installation, Integration, IntegrationFieldMapping, Project, ProviderApp, ProviderInfo, UpdateInstallationOperationRequest, UpdateInstallationRequestInstallationConfig } from '../../generated-sources/api/src';
|
|
1
|
+
import { Config, Connection, CreateInstallationOperationRequest, CreateInstallationRequestConfig, HydratedIntegrationField, HydratedIntegrationFieldExistent, HydratedIntegrationObject, HydratedIntegrationRead, HydratedIntegrationWrite, HydratedIntegrationWriteObject, HydratedRevision, Installation, Integration, IntegrationFieldMapping, OauthConnectOperationRequest, Project, ProviderApp, ProviderInfo, UpdateInstallationOperationRequest, UpdateInstallationRequestInstallationConfig } from '../../generated-sources/api/src';
|
|
2
2
|
import { ApiService } from './ApiService';
|
|
3
3
|
export declare const AMP_SERVER: string;
|
|
4
4
|
export declare const AMP_API_ROOT: string;
|
|
@@ -7,4 +7,4 @@ export declare const api: () => ApiService;
|
|
|
7
7
|
/**
|
|
8
8
|
* Types exported from generated api
|
|
9
9
|
*/
|
|
10
|
-
export type { Config, Connection, CreateInstallationOperationRequest, CreateInstallationRequestConfig, HydratedIntegrationRead, HydratedIntegrationWrite, HydratedIntegrationWriteObject, HydratedIntegrationObject, HydratedIntegrationField, HydratedRevision, Installation, Integration, HydratedIntegrationFieldExistent, IntegrationFieldMapping, Project, ProviderApp, ProviderInfo, UpdateInstallationOperationRequest, UpdateInstallationRequestInstallationConfig, };
|
|
10
|
+
export type { Config, Connection, CreateInstallationOperationRequest, CreateInstallationRequestConfig, HydratedIntegrationRead, HydratedIntegrationWrite, HydratedIntegrationWriteObject, HydratedIntegrationObject, HydratedIntegrationField, HydratedRevision, Installation, Integration, HydratedIntegrationFieldExistent, IntegrationFieldMapping, OauthConnectOperationRequest, Project, ProviderApp, ProviderInfo, UpdateInstallationOperationRequest, UpdateInstallationRequestInstallationConfig, };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const LIB_VERSION = "1.5.
|
|
1
|
+
export declare const LIB_VERSION = "1.5.2";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@amp-labs/react",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.2",
|
|
4
4
|
"description": "Ampersand React library.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Ampersand Labs",
|
|
@@ -49,12 +49,12 @@
|
|
|
49
49
|
"@openapitools/openapi-generator-cli": "^2.7.0",
|
|
50
50
|
"@types/lodash.isequal": "^4.5.7",
|
|
51
51
|
"@types/react": "^18.2.33",
|
|
52
|
-
"@typescript-eslint/eslint-plugin": "^
|
|
53
|
-
"@typescript-eslint/parser": "^
|
|
52
|
+
"@typescript-eslint/eslint-plugin": "^7.10.0",
|
|
53
|
+
"@typescript-eslint/parser": "^7.10.0",
|
|
54
54
|
"babel-jest": "^29.7.0",
|
|
55
55
|
"eslint": "^8.52.0",
|
|
56
56
|
"eslint-config-airbnb": "^19.0.4",
|
|
57
|
-
"eslint-config-airbnb-typescript": "^
|
|
57
|
+
"eslint-config-airbnb-typescript": "^18.0.0",
|
|
58
58
|
"eslint-plugin-import": "^2.29.0",
|
|
59
59
|
"eslint-plugin-jsx-a11y": "^6.8.0",
|
|
60
60
|
"eslint-plugin-n": "^17.2.0",
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* OAuthPopup.tsx
|
|
3
|
-
*
|
|
4
|
-
* Takes a URL and creates a popup showing that page.
|
|
5
|
-
*/
|
|
6
|
-
import React from 'react';
|
|
7
|
-
type PopupProps = {
|
|
8
|
-
url: string | null;
|
|
9
|
-
title: string;
|
|
10
|
-
onClose: (err: string | null) => void;
|
|
11
|
-
children: React.ReactNode;
|
|
12
|
-
};
|
|
13
|
-
declare function OAuthPopup({ title, url, children, onClose, }: PopupProps): import("react/jsx-runtime").JSX.Element;
|
|
14
|
-
export default OAuthPopup;
|
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
4
|
-
/**
|
|
5
|
-
* OAuthPopup.tsx
|
|
6
|
-
*
|
|
7
|
-
* Takes a URL and creates a popup showing that page.
|
|
8
|
-
*/
|
|
9
|
-
const react_1 = require("react");
|
|
10
|
-
const ApiKeyContextProvider_1 = require("../../context/ApiKeyContextProvider");
|
|
11
|
-
const ConnectionsContextProvider_1 = require("../../context/ConnectionsContextProvider");
|
|
12
|
-
const ProjectContextProvider_1 = require("../../context/ProjectContextProvider");
|
|
13
|
-
const api_1 = require("../../services/api");
|
|
14
|
-
const DEFAULT_WIDTH = 600; // px
|
|
15
|
-
const DEFAULT_HEIGHT = 600; // px
|
|
16
|
-
const DEFAULT_INTERVAL = 500; // ms
|
|
17
|
-
const SUCCESS_EVENT = 'AUTHORIZATION_SUCCEEDED';
|
|
18
|
-
const FAILURE_EVENT = 'AUTHORIZATION_FAILED';
|
|
19
|
-
const createPopup = ({ url, title, }) => {
|
|
20
|
-
const left = window.screenX + (window.outerWidth - DEFAULT_WIDTH) / 2;
|
|
21
|
-
const top = window.screenY + (window.outerHeight - DEFAULT_HEIGHT) / 2.5; // a lil shorter
|
|
22
|
-
const popup = window.open(url, title, `width=${DEFAULT_WIDTH},height=${DEFAULT_HEIGHT},left=${left},top=${top}`);
|
|
23
|
-
return popup;
|
|
24
|
-
};
|
|
25
|
-
function OAuthPopup({ title = '', url, children, onClose, }) {
|
|
26
|
-
const { projectId } = (0, ProjectContextProvider_1.useProject)();
|
|
27
|
-
const apiKey = (0, ApiKeyContextProvider_1.useApiKey)();
|
|
28
|
-
const [externalWindow, setExternalWindow] = (0, react_1.useState)();
|
|
29
|
-
const intervalRef = (0, react_1.useRef)();
|
|
30
|
-
const clearTimer = () => window.clearInterval(intervalRef.current);
|
|
31
|
-
const { setSelectedConnection } = (0, ConnectionsContextProvider_1.useConnections)();
|
|
32
|
-
(0, react_1.useEffect)(() => {
|
|
33
|
-
if (url)
|
|
34
|
-
setExternalWindow(createPopup({ url, title }));
|
|
35
|
-
}, [url, title]);
|
|
36
|
-
const refreshConnections = (0, react_1.useCallback)(async (connectionId) => {
|
|
37
|
-
const connection = await (0, api_1.api)().connectionApi.getConnection({ projectId, connectionId }, {
|
|
38
|
-
headers: { 'X-Api-Key': apiKey !== null && apiKey !== void 0 ? apiKey : '' },
|
|
39
|
-
});
|
|
40
|
-
setSelectedConnection(connection);
|
|
41
|
-
}, [projectId, apiKey, setSelectedConnection]);
|
|
42
|
-
(0, react_1.useEffect)(() => {
|
|
43
|
-
window.addEventListener('message', (event) => {
|
|
44
|
-
var _a, _b, _c, _d, _e;
|
|
45
|
-
if (event.origin === api_1.AMP_SERVER) {
|
|
46
|
-
// this event come from our own server
|
|
47
|
-
if (((_a = event.data) === null || _a === void 0 ? void 0 : _a.eventType) === SUCCESS_EVENT) {
|
|
48
|
-
clearTimer();
|
|
49
|
-
const connectionId = (_b = event.data.data) === null || _b === void 0 ? void 0 : _b.connection;
|
|
50
|
-
if (!connectionId) {
|
|
51
|
-
console.error('Ampersand server returned a successful authorization event, but did not return a connection ID.');
|
|
52
|
-
onClose('There is an unexpected server issue.');
|
|
53
|
-
}
|
|
54
|
-
else {
|
|
55
|
-
refreshConnections(connectionId);
|
|
56
|
-
onClose(null);
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
else if (((_c = event.data) === null || _c === void 0 ? void 0 : _c.eventType) === FAILURE_EVENT) {
|
|
60
|
-
clearTimer();
|
|
61
|
-
onClose((_e = (_d = event.data.data) === null || _d === void 0 ? void 0 : _d.message) !== null && _e !== void 0 ? _e : 'There was an error logging you in. Please try again.');
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
});
|
|
65
|
-
}, [externalWindow, onClose, refreshConnections]);
|
|
66
|
-
(0, react_1.useEffect)(() => {
|
|
67
|
-
if (externalWindow && !intervalRef.current) {
|
|
68
|
-
intervalRef.current = window.setInterval(() => {
|
|
69
|
-
// Check if window was closed prematurely.
|
|
70
|
-
if (!externalWindow || externalWindow.closed) {
|
|
71
|
-
clearTimer();
|
|
72
|
-
onClose('The popup was closed too quickly. Please try again.');
|
|
73
|
-
}
|
|
74
|
-
}, DEFAULT_INTERVAL);
|
|
75
|
-
}
|
|
76
|
-
}, [externalWindow, onClose]);
|
|
77
|
-
return ((0, jsx_runtime_1.jsx)("div", { children: children }));
|
|
78
|
-
}
|
|
79
|
-
exports.default = OAuthPopup;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const fetchOAuthCallbackURL: (projectId: string, consumerRef: string, groupRef: string, apiKey: string, provider: string, workspace?: string, consumerName?: string, groupName?: string) => Promise<string>;
|