diff --git a/.version b/.version
index 9db2e998b3..456312b41f 100644
--- a/.version
+++ b/.version
@@ -1 +1 @@
-2.67.1
+2.67.2
diff --git a/frontend/.version b/frontend/.version
index 9db2e998b3..456312b41f 100644
--- a/frontend/.version
+++ b/frontend/.version
@@ -1 +1 @@
-2.67.1
+2.67.2
diff --git a/frontend/src/Oauth2/Authorize.jsx b/frontend/src/Oauth2/Authorize.jsx
index ef0dfaed8c..73c21e7282 100644
--- a/frontend/src/Oauth2/Authorize.jsx
+++ b/frontend/src/Oauth2/Authorize.jsx
@@ -40,6 +40,14 @@ class AuthorizeComponent extends React.Component {
localStorage.setItem('OAuthCode', code);
this.setState({ isLoading: false, authSuccess: true });
}
+
+ this.timer = setTimeout(() => {
+ window.close();
+ }, 2000);
+ }
+
+ componentWillUnmount() {
+ clearTimeout(this.timer);
}
render() {
@@ -105,7 +113,14 @@ class AuthorizeComponent extends React.Component {
Success
-
Authorization successful, you can close this tab now.
+
Authorization successful! You will be redirected in a few seconds.
+
+ Don’t want to wait?{' '}
+ window.close()}>
+ Click here
+ {' '}
+ to go now.
+
)}
diff --git a/frontend/src/_components/DynamicForm.jsx b/frontend/src/_components/DynamicForm.jsx
index 37fd3104af..c81395beac 100644
--- a/frontend/src/_components/DynamicForm.jsx
+++ b/frontend/src/_components/DynamicForm.jsx
@@ -19,6 +19,7 @@ import { orgEnvironmentVariableService, orgEnvironmentConstantService } from '..
import { find, isEmpty } from 'lodash';
import { ButtonSolid } from './AppButton';
import { Constants } from '@/_helpers/utils';
+import Sharepoint from '@/_components/Sharepoint';
const DynamicForm = ({
schema,
@@ -160,6 +161,8 @@ const DynamicForm = ({
return CondtionSort;
case 'react-component-salesforce':
return Salesforce;
+ case 'react-component-sharepoint':
+ return Sharepoint;
default:
return Type is invalid
;
}
@@ -304,6 +307,7 @@ const DynamicForm = ({
case 'react-component-slack':
case 'react-component-zendesk':
case 'react-component-salesforce':
+ case 'react-component-sharepoint':
return {
optionchanged,
createDataSource,
diff --git a/frontend/src/_components/Sharepoint.jsx b/frontend/src/_components/Sharepoint.jsx
new file mode 100644
index 0000000000..c6d6271378
--- /dev/null
+++ b/frontend/src/_components/Sharepoint.jsx
@@ -0,0 +1,146 @@
+import React, { useState } from 'react';
+import { datasourceService } from '@/_services';
+import { useTranslation } from 'react-i18next';
+import { toast } from 'react-hot-toast';
+import Button from '@/_ui/Button';
+import Input from '@/_ui/Input';
+import cx from 'classnames';
+
+const Sharepoint = ({
+ optionchanged,
+ createDataSource,
+ options,
+ isSaving,
+ selectedDataSource,
+ currentAppEnvironmentId,
+ workspaceConstants,
+ isDisabled,
+}) => {
+ const [authStatus, setAuthStatus] = useState(null);
+ const { t } = useTranslation();
+
+ const hostUrl = window.public_config?.TOOLJET_HOST;
+ const subPathUrl = window.public_config?.SUB_PATH;
+ const fullUrl = `${hostUrl}${subPathUrl ? subPathUrl : '/'}oauth2/authorize`;
+ const redirectUri = fullUrl;
+
+ function authSharepoint() {
+ const provider = 'sharepoint';
+ const plugin_id = selectedDataSource?.plugin?.id;
+ const source_options = options;
+ setAuthStatus('waiting_for_url');
+
+ const scope = 'https://graph.microsoft.com/.default+offline_access';
+
+ datasourceService
+ .fetchOauth2BaseUrl(provider, plugin_id, source_options)
+ .then((data) => {
+ const authUrl = `${data.url}&scope=${scope}&state=12345&response_mode=query`;
+ localStorage.setItem('sourceWaitingForOAuth', 'newSource');
+ localStorage.setItem('currentAppEnvironmentIdForOauth', currentAppEnvironmentId);
+ optionchanged('provider', provider).then(() => {
+ optionchanged('oauth2', true);
+ optionchanged('plugin_id', plugin_id);
+ });
+ setAuthStatus('waiting_for_token');
+ openUrl(authUrl);
+ })
+ .catch(({ error }) => {
+ toast.error(error);
+ setAuthStatus(null);
+ });
+ }
+
+ function saveDataSource() {
+ optionchanged('code', localStorage.getItem('OAuthCode')).then(() => {
+ createDataSource();
+ });
+ }
+
+ function openUrl(url) {
+ const width = window.innerWidth * 0.4;
+ const height = window.innerHeight * 0.8;
+ const left = window.screenX + (window.innerWidth - width) / 2;
+ const top = window.screenY + (window.innerHeight - height) / 2;
+ const windowFeatures = `width=${width},height=${height},top=${top},left=${left},resizable=yes,scrollbars=yes`;
+ const authWindow = window.open(url, '_blank', windowFeatures);
+ if (authWindow) {
+ authWindow.focus();
+ }
+ }
+
+ return (
+
+
+
+ optionchanged('sp_client_id', e.target.value)}
+ value={options?.sp_client_id?.value ?? ''}
+ placeholder="Enter client ID"
+ workspaceConstants={workspaceConstants}
+ />
+
+
+
+ optionchanged('sp_client_secret', e.target.value)}
+ value={options?.sp_client_secret?.value || ''}
+ placeholder="**************"
+ workspaceConstants={workspaceConstants}
+ encrypted={true}
+ />
+
+
+
+ optionchanged('sp_tenant_id', e.target.value)}
+ value={options?.sp_tenant_id?.value ?? ''}
+ placeholder="Enter tenant ID"
+ workspaceConstants={workspaceConstants}
+ />
+
+
+
+
+
+
+
+ {authStatus === 'waiting_for_token' && (
+
+
+
+ )}
+
+ {(!authStatus || authStatus === 'waiting_for_url') && (
+
+ )}
+
+
+
+ );
+};
+export default Sharepoint;
diff --git a/marketplace/package-lock.json b/marketplace/package-lock.json
index b1b9370125..8b3739b9c0 100644
--- a/marketplace/package-lock.json
+++ b/marketplace/package-lock.json
@@ -5880,6 +5880,10 @@
"resolved": "plugins/salesforce",
"link": true
},
+ "node_modules/@tooljet-marketplace/sharepoint": {
+ "resolved": "plugins/sharepoint",
+ "link": true
+ },
"node_modules/@tooljet-marketplace/supabase": {
"resolved": "plugins/supabase",
"link": true
@@ -17323,6 +17327,17 @@
"typescript": "^4.7.4"
}
},
+ "plugins/sharepoint": {
+ "name": "@tooljet-marketplace/sharepoint",
+ "version": "1.0.0",
+ "dependencies": {
+ "@tooljet-marketplace/common": "^1.0.0"
+ },
+ "devDependencies": {
+ "@vercel/ncc": "^0.34.0",
+ "typescript": "^4.7.4"
+ }
+ },
"plugins/supabase": {
"name": "@tooljet-marketplace/supabase",
"version": "1.0.0",
diff --git a/marketplace/plugins/sharepoint/.gitignore b/marketplace/plugins/sharepoint/.gitignore
new file mode 100644
index 0000000000..23e6609462
--- /dev/null
+++ b/marketplace/plugins/sharepoint/.gitignore
@@ -0,0 +1,5 @@
+node_modules
+lib/*.d.*
+lib/*.js
+lib/*.js.map
+dist/*
\ No newline at end of file
diff --git a/marketplace/plugins/sharepoint/README.md b/marketplace/plugins/sharepoint/README.md
new file mode 100644
index 0000000000..dad9d32646
--- /dev/null
+++ b/marketplace/plugins/sharepoint/README.md
@@ -0,0 +1,4 @@
+
+# Sharepoint
+
+Documentation on: https://docs.tooljet.com/docs/data-sources/sharepoint
\ No newline at end of file
diff --git a/marketplace/plugins/sharepoint/__tests__/index.js b/marketplace/plugins/sharepoint/__tests__/index.js
new file mode 100644
index 0000000000..ba42184604
--- /dev/null
+++ b/marketplace/plugins/sharepoint/__tests__/index.js
@@ -0,0 +1,7 @@
+'use strict';
+
+const sharepoint = require('../lib');
+
+describe('sharepoint', () => {
+ it.todo('needs tests');
+});
diff --git a/marketplace/plugins/sharepoint/lib/icon.svg b/marketplace/plugins/sharepoint/lib/icon.svg
new file mode 100644
index 0000000000..455a9482d1
--- /dev/null
+++ b/marketplace/plugins/sharepoint/lib/icon.svg
@@ -0,0 +1,23 @@
+
\ No newline at end of file
diff --git a/marketplace/plugins/sharepoint/lib/index.ts b/marketplace/plugins/sharepoint/lib/index.ts
new file mode 100644
index 0000000000..4265a8f007
--- /dev/null
+++ b/marketplace/plugins/sharepoint/lib/index.ts
@@ -0,0 +1,353 @@
+import { OAuthUnauthorizedClientError, QueryError, QueryResult, QueryService } from '@tooljet-marketplace/common';
+import { SourceOptions, QueryOptions } from './types';
+
+export default class Sharepoint implements QueryService {
+ authUrl(sourceOptions): string {
+ const host = process.env.TOOLJET_HOST;
+ const subpath = process.env.SUB_PATH;
+ const fullUrl = `${host}${subpath ? subpath : '/'}`;
+ const clientId = sourceOptions.sp_client_id;
+ const clientSecret = sourceOptions.sp_client_secret.value;
+ const tenant = sourceOptions.sp_tenant_id;
+
+ if (!clientId || !clientSecret || !tenant) {
+ throw Error('You need to enter the client ID, client secret and tenant ID for authentication.');
+ }
+
+ return (
+ 'https://login.microsoftonline.com/common/oauth2/v2.0/authorize' +
+ `?client_id=${clientId.value}&response_type=code` +
+ `&redirect_uri=${fullUrl}oauth2/authorize`
+ );
+ }
+
+ async accessDetailsFrom(authCode: string, sourceOptions: any, resetSecureData = false): Promise