@yeclimeric/nocobase-plugin-dingtalk 1.9.1

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/CHANGELOG.md ADDED
@@ -0,0 +1,5 @@
1
+ ## 更新日志
2
+
3
+ ### 20240723
4
+
5
+ - 支持钉钉第三方登录
package/README.md ADDED
@@ -0,0 +1,14 @@
1
+ # @yeclimeric/nocobase-plugin-dingtalk
2
+
3
+ ## 功能
4
+
5
+ - nocobase插件,支持钉钉登录
6
+
7
+ ## 说明
8
+ ### 版本对应
9
+ - 前两位版本号与nocobase主版本号保持一致,第三位为构建版本号。
10
+ - 建议使用与nocobase相同版本号的插件
11
+
12
+ 使用的老版本的钉钉接口,后续会逐步的升级完善
13
+
14
+ fork from https://github.com/ruanjf/nocobase-plugins
@@ -0,0 +1,8 @@
1
+ import React from 'react';
2
+ import type { Authenticator } from '@nocobase/plugin-auth/client';
3
+ export declare const DingTalkAuthButton: (props: {
4
+ authenticator: Authenticator;
5
+ }) => React.JSX.Element;
6
+ export declare const DingTalkAuthAdminSettingsForm: (props: {
7
+ authenticator: Authenticator;
8
+ }) => React.JSX.Element;
@@ -0,0 +1,7 @@
1
+ import { Plugin } from '@nocobase/client';
2
+ export declare class NocobasePluginDingTalkClient extends Plugin {
3
+ afterAdd(): Promise<void>;
4
+ beforeLoad(): Promise<void>;
5
+ load(): Promise<void>;
6
+ }
7
+ export default NocobasePluginDingTalkClient;
@@ -0,0 +1,10 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
9
+
10
+ !function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("react"),require("@nocobase/plugin-auth/client"),require("@nocobase/client"),require("@ant-design/icons"),require("antd")):"function"==typeof define&&define.amd?define("@yeclimeric/nocobase-plugin-dingtalk",["react","@nocobase/plugin-auth/client","@nocobase/client","@ant-design/icons","antd"],t):"object"==typeof exports?exports["@yeclimeric/nocobase-plugin-dingtalk"]=t(require("react"),require("@nocobase/plugin-auth/client"),require("@nocobase/client"),require("@ant-design/icons"),require("antd")):e["@yeclimeric/nocobase-plugin-dingtalk"]=t(e.react,e["@nocobase/plugin-auth/client"],e["@nocobase/client"],e["@ant-design/icons"],e.antd)}(self,function(e,t,n,r,o){return function(){"use strict";var i={482:function(e){e.exports=r},772:function(e){e.exports=n},689:function(e){e.exports=t},721:function(e){e.exports=o},156:function(t){t.exports=e}},u={};function a(e){var t=u[e];if(void 0!==t)return t.exports;var n=u[e]={exports:{}};return i[e](n,n.exports,a),n.exports}a.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return a.d(t,{a:t}),t},a.d=function(e,t){for(var n in t)a.o(t,n)&&!a.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},a.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},a.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var c={};return!function(){a.r(c),a.d(c,{NocobasePluginDingTalkClient:function(){return w},default:function(){return S}});var e=a(772),t=a(689),n=a.n(t),r=a(156),o=a.n(r),i=a(721),u=a(482);function l(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n<t;n++)r[n]=e[n];return r}function s(e,t,n,r,o,i,u){try{var a=e[i](u),c=a.value}catch(e){n(e);return}a.done?t(c):Promise.resolve(c).then(r,o)}var f=function(t){var n,a,c,f=(n=(0,r.useState)(!1),function(e){if(Array.isArray(e))return e}(n)||function(e,t){var n,r,o=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=o){var i=[],u=!0,a=!1;try{for(o=o.call(e);!(u=(n=o.next()).done)&&(i.push(n.value),i.length!==t);u=!0);}catch(e){a=!0,r=e}finally{try{u||null==o.return||o.return()}finally{if(a)throw r}}return i}}(n,2)||function(e,t){if(e){if("string"==typeof e)return l(e,2);var n=Object.prototype.toString.call(e).slice(8,-1);if("Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n)return Array.from(n);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return l(e,t)}}(n,2)||function(){throw TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()),p=f[0],y=f[1],b=(0,e.useResource)("community-ding-talk"),d=(a=function(){var e;return function(e,t){var n,r,o,i,u={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:a(0),throw:a(1),return:a(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function a(i){return function(a){var c=[i,a];if(n)throw TypeError("Generator is already executing.");for(;u;)try{if(n=1,r&&(o=2&c[0]?r.return:c[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,c[1])).done)return o;switch(r=0,o&&(c=[2&c[0],o.value]),c[0]){case 0:case 1:o=c;break;case 4:return u.label++,{value:c[1],done:!1};case 5:u.label++,r=c[1],c=[0];continue;case 7:c=u.ops.pop(),u.trys.pop();continue;default:if(!(o=(o=u.trys).length>0&&o[o.length-1])&&(6===c[0]||2===c[0])){u=0;continue}if(3===c[0]&&(!o||c[1]>o[0]&&c[1]<o[3])){u.label=c[1];break}if(6===c[0]&&u.label<o[1]){u.label=o[1],o=c;break}if(o&&u.label<o[2]){u.label=o[2],u.ops.push(c);break}o[2]&&u.ops.pop(),u.trys.pop();continue}c=t.call(e,u)}catch(e){c=[6,e],r=0}finally{n=o=0}if(5&c[0])throw c[1];return{value:c[0]?c[1]:void 0,done:!0}}}}(this,function(n){switch(n.label){case 0:y(!0),n.label=1;case 1:return n.trys.push([1,,3,4]),[4,b.getAuthUrl({values:{authenticator:t.authenticator.name,redirect:new URLSearchParams(location.search?location.search.substring(1):"").get("redirect")||""}})];case 2:return console.log("uu",e=n.sent(),e.data),location.href=e.data.data,[3,4];case 3:return setTimeout(function(){y(!1)},1e3),[7];case 4:return[2]}})},c=function(){var e=this,t=arguments;return new Promise(function(n,r){var o=a.apply(e,t);function i(e){s(o,n,r,i,u,"next",e)}function u(e){s(o,n,r,i,u,"throw",e)}i(void 0)})},function(){return c.apply(this,arguments)});return o().createElement(i.Button,{loading:p,disabled:p,icon:o().createElement(u.DingtalkOutlined,null),style:{width:"100%"},onClick:d},t.authenticator.title||t.authenticator.name)},p=function(t){return console.log("aaa",t),o().createElement(e.SchemaComponent,{schema:{type:"object",properties:{communityDingTalkAuth:{type:"void",properties:{public:{type:"object",properties:{autoSignup:{"x-decorator":"FormItem",type:"boolean",title:"用户不存在时自动注册",required:!1,"x-component":"Checkbox"}}},internal:{type:"object",properties:{userCheckType:{"x-decorator":"FormItem",type:"string",title:"用户验证方式",required:!0,"x-component":"Select","x-component-props":{options:[{value:"orgEmail",label:"企业邮箱"},{value:"personalEmail",label:"个人邮箱"},{value:"mobile",label:"手机号"}]}},emailDomain:{"x-decorator":"FormItem",type:"string",title:"邮箱域名,多个使用英文逗号分隔",required:!0,"x-component":"Input"},appKey:{"x-decorator":"FormItem",type:"string",title:"应用ID",required:!0,"x-component":"Input"},appSecret:{"x-decorator":"FormItem",type:"string",title:"应用秘钥",required:!0,"x-component":"Password"}}}}}}}})};function y(e,t,n,r,o,i,u){try{var a=e[i](u),c=a.value}catch(e){n(e);return}a.done?t(c):Promise.resolve(c).then(r,o)}function b(e){return function(){var t=this,n=arguments;return new Promise(function(r,o){var i=e.apply(t,n);function u(e){y(i,r,o,u,a,"next",e)}function a(e){y(i,r,o,u,a,"throw",e)}u(void 0)})}}function d(e,t,n){return(d=g()?Reflect.construct:function(e,t,n){var r=[null];r.push.apply(r,t);var o=new(Function.bind.apply(e,r));return n&&m(o,n.prototype),o}).apply(null,arguments)}function h(e){return(h=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)})(e)}function m(e,t){return(m=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e})(e,t)}function v(e){var t="function"==typeof Map?new Map:void 0;return(v=function(e){if(null===e||-1===Function.toString.call(e).indexOf("[native code]"))return e;if("function"!=typeof e)throw TypeError("Super expression must either be null or a function");if(void 0!==t){if(t.has(e))return t.get(e);t.set(e,n)}function n(){return d(e,arguments,h(this).constructor)}return n.prototype=Object.create(e.prototype,{constructor:{value:n,enumerable:!1,writable:!0,configurable:!0}}),m(n,e)})(e)}function g(){try{var e=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){}))}catch(e){}return(g=function(){return!!e})()}function x(e,t){var n,r,o,i,u={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:a(0),throw:a(1),return:a(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function a(i){return function(a){var c=[i,a];if(n)throw TypeError("Generator is already executing.");for(;u;)try{if(n=1,r&&(o=2&c[0]?r.return:c[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,c[1])).done)return o;switch(r=0,o&&(c=[2&c[0],o.value]),c[0]){case 0:case 1:o=c;break;case 4:return u.label++,{value:c[1],done:!1};case 5:u.label++,r=c[1],c=[0];continue;case 7:c=u.ops.pop(),u.trys.pop();continue;default:if(!(o=(o=u.trys).length>0&&o[o.length-1])&&(6===c[0]||2===c[0])){u=0;continue}if(3===c[0]&&(!o||c[1]>o[0]&&c[1]<o[3])){u.label=c[1];break}if(6===c[0]&&u.label<o[1]){u.label=o[1],o=c;break}if(o&&u.label<o[2]){u.label=o[2],u.ops.push(c);break}o[2]&&u.ops.pop(),u.trys.pop();continue}c=t.call(e,u)}catch(e){c=[6,e],r=0}finally{n=o=0}if(5&c[0])throw c[1];return{value:c[0]?c[1]:void 0,done:!0}}}}var w=function(e){var t;if("function"!=typeof e&&null!==e)throw TypeError("Super expression must either be null or a function");function r(){var e,t;if(!(this instanceof r))throw TypeError("Cannot call a class as a function");return e=r,t=arguments,e=h(e),function(e,t){var n;if(t&&("object"==((n=t)&&"undefined"!=typeof Symbol&&n.constructor===Symbol?"symbol":typeof n)||"function"==typeof t))return t;if(void 0===e)throw ReferenceError("this hasn't been initialised - super() hasn't been called");return e}(this,g()?Reflect.construct(e,t||[],h(this).constructor):e.apply(this,t))}return r.prototype=Object.create(e&&e.prototype,{constructor:{value:r,writable:!0,configurable:!0}}),e&&m(r,e),t=[{key:"afterAdd",value:function(){return b(function(){return x(this,function(e){return[2]})})()}},{key:"beforeLoad",value:function(){return b(function(){return x(this,function(e){return[2]})})()}},{key:"load",value:function(){var e=this;return b(function(){return x(this,function(t){return e.app.pm.get(n()).registerType("community-ding-talk-auth",{components:{SignInButton:f,AdminSettingsForm:p}}),[2]})})()}}],function(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}(r.prototype,t),r}(v(e.Plugin)),S=w}(),c}()});
@@ -0,0 +1,2 @@
1
+ export declare const NAMESPACE = "community-ding-talk";
2
+ export declare function usePluginTranslation(): import("react-i18next").UseTranslationResponse<"community-ding-talk", undefined>;
@@ -0,0 +1,20 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
9
+
10
+ module.exports = {
11
+ "@nocobase/client": "1.9.26",
12
+ "@nocobase/plugin-auth": "1.9.26",
13
+ "@nocobase/server": "1.9.26",
14
+ "react": "18.3.1",
15
+ "antd": "5.12.8",
16
+ "@ant-design/icons": "5.6.1",
17
+ "react-i18next": "11.18.6",
18
+ "@nocobase/actions": "1.9.26",
19
+ "@nocobase/auth": "1.9.26"
20
+ };
@@ -0,0 +1,2 @@
1
+ export * from './server';
2
+ export { default } from './server';
package/dist/index.js ADDED
@@ -0,0 +1,48 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
9
+
10
+ var __create = Object.create;
11
+ var __defProp = Object.defineProperty;
12
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
13
+ var __getOwnPropNames = Object.getOwnPropertyNames;
14
+ var __getProtoOf = Object.getPrototypeOf;
15
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
16
+ var __export = (target, all) => {
17
+ for (var name in all)
18
+ __defProp(target, name, { get: all[name], enumerable: true });
19
+ };
20
+ var __copyProps = (to, from, except, desc) => {
21
+ if (from && typeof from === "object" || typeof from === "function") {
22
+ for (let key of __getOwnPropNames(from))
23
+ if (!__hasOwnProp.call(to, key) && key !== except)
24
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
25
+ }
26
+ return to;
27
+ };
28
+ var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
29
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
30
+ // If the importer is in node compatibility mode or this is not an ESM
31
+ // file that has been converted to a CommonJS file using a Babel-
32
+ // compatible transform (i.e. "__esModule" has not been set), then set
33
+ // "default" to the CommonJS "module.exports" for node compatibility.
34
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
35
+ mod
36
+ ));
37
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
38
+ var src_exports = {};
39
+ __export(src_exports, {
40
+ default: () => import_server.default
41
+ });
42
+ module.exports = __toCommonJS(src_exports);
43
+ __reExport(src_exports, require("./server"), module.exports);
44
+ var import_server = __toESM(require("./server"));
45
+ // Annotate the CommonJS export names for ESM import in node:
46
+ 0 && (module.exports = {
47
+ ...require("./server")
48
+ });
@@ -0,0 +1,5 @@
1
+ declare const _default: {
2
+ 'User will be registered automatically if not exists.': string;
3
+ 'Sign up automatically when the user does not exist': string;
4
+ };
5
+ export default _default;
@@ -0,0 +1,35 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
9
+
10
+ var __defProp = Object.defineProperty;
11
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
12
+ var __getOwnPropNames = Object.getOwnPropertyNames;
13
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
14
+ var __export = (target, all) => {
15
+ for (var name in all)
16
+ __defProp(target, name, { get: all[name], enumerable: true });
17
+ };
18
+ var __copyProps = (to, from, except, desc) => {
19
+ if (from && typeof from === "object" || typeof from === "function") {
20
+ for (let key of __getOwnPropNames(from))
21
+ if (!__hasOwnProp.call(to, key) && key !== except)
22
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
23
+ }
24
+ return to;
25
+ };
26
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
27
+ var zh_CN_exports = {};
28
+ __export(zh_CN_exports, {
29
+ default: () => zh_CN_default
30
+ });
31
+ module.exports = __toCommonJS(zh_CN_exports);
32
+ var zh_CN_default = {
33
+ "User will be registered automatically if not exists.": "\u7528\u6237\u4E0D\u5B58\u5728\u65F6\u5C06\u81EA\u52A8\u6CE8\u518C\u3002",
34
+ "Sign up automatically when the user does not exist": "\u7528\u6237\u4E0D\u5B58\u5728\u65F6\u81EA\u52A8\u6CE8\u518C"
35
+ };
@@ -0,0 +1,5 @@
1
+ import { Context, Next } from '@nocobase/actions';
2
+ export declare const dingTalkActions: {
3
+ getAuthUrl: (ctx: Context, next: Next) => Promise<void>;
4
+ redirectAuth: (ctx: Context, next: Next) => Promise<void>;
5
+ };
@@ -0,0 +1,75 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
9
+
10
+ var __defProp = Object.defineProperty;
11
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
12
+ var __getOwnPropNames = Object.getOwnPropertyNames;
13
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
14
+ var __export = (target, all) => {
15
+ for (var name in all)
16
+ __defProp(target, name, { get: all[name], enumerable: true });
17
+ };
18
+ var __copyProps = (to, from, except, desc) => {
19
+ if (from && typeof from === "object" || typeof from === "function") {
20
+ for (let key of __getOwnPropNames(from))
21
+ if (!__hasOwnProp.call(to, key) && key !== except)
22
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
23
+ }
24
+ return to;
25
+ };
26
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
27
+ var dingTalkActions_exports = {};
28
+ __export(dingTalkActions_exports, {
29
+ dingTalkActions: () => dingTalkActions
30
+ });
31
+ module.exports = __toCommonJS(dingTalkActions_exports);
32
+ function getReqUrl(req) {
33
+ var _a, _b, _c, _d;
34
+ const proto = ((_b = (_a = req.get("X-Forwarded-Proto")) == null ? void 0 : _a.split(",")) == null ? void 0 : _b[0]) || req.protocol;
35
+ const host = ((_d = (_c = req.get("X-Forwarded-Host")) == null ? void 0 : _c.split(",")) == null ? void 0 : _d[0]) || req.host;
36
+ return process.env.APP_URL || `${proto}://${host}${process.env.APP_PUBLIC_PATH || "/"}`;
37
+ }
38
+ const dingTalkActions = {
39
+ getAuthUrl: async (ctx, next) => {
40
+ const { authenticator: authenticatorName, redirect } = ctx.action.params.values;
41
+ if (!authenticatorName) {
42
+ ctx.throw(400, "\u8BA4\u8BC1\u5668\u4E0D\u80FD\u4E3A\u7A7A");
43
+ }
44
+ const app = ctx.app;
45
+ const auth = await app.authManager.get(authenticatorName, ctx);
46
+ const redirectUri = `${getReqUrl(ctx.request)}api/community-ding-talk:redirectAuth?authenticator=${encodeURIComponent(authenticatorName)}&redirect=${encodeURIComponent(redirect || "")}`;
47
+ ctx.body = auth.dingTalkApi.getLoginUrl(redirectUri);
48
+ await next();
49
+ },
50
+ redirectAuth: async (ctx, next) => {
51
+ const { authenticator: authenticatorName, redirect, code, authCode, state } = ctx.action.params;
52
+ if (!authenticatorName) {
53
+ ctx.throw(400, "\u8BA4\u8BC1\u5668\u4E0D\u80FD\u4E3A\u7A7A");
54
+ }
55
+ if (!code) {
56
+ ctx.throw(400, "OAuth 2.0 \u4E34\u65F6\u6388\u6743\u7801\u4E0D\u5B58\u5728");
57
+ }
58
+ const app = ctx.app;
59
+ const auth = await app.authManager.get(authenticatorName, ctx);
60
+ const { user, token } = await auth.signIn();
61
+ let rediretPath = redirect;
62
+ if (rediretPath) {
63
+ if (rediretPath.startsWith("/")) {
64
+ rediretPath = rediretPath.substring(1);
65
+ }
66
+ } else {
67
+ rediretPath = "";
68
+ }
69
+ ctx.redirect(`${(process.env.APP_PUBLIC_PATH || "/") + rediretPath}?authenticator=${encodeURIComponent(authenticatorName)}&token=${encodeURIComponent(token)}`);
70
+ }
71
+ };
72
+ // Annotate the CommonJS export names for ESM import in node:
73
+ 0 && (module.exports = {
74
+ dingTalkActions
75
+ });
@@ -0,0 +1,20 @@
1
+ import { BaseAuth, AuthConfig } from '@nocobase/auth';
2
+ import { DingTalkApi } from '../openapi/dingTalkApi';
3
+ export type AuthConfigOptions = {
4
+ public: {
5
+ autoSignup: boolean;
6
+ };
7
+ internal: {
8
+ userCheckType: 'orgEmail' | 'personalEmail' | 'mobile';
9
+ emailDomains: string[];
10
+ appKey?: string;
11
+ appSecret?: string;
12
+ };
13
+ };
14
+ export declare class DingTalkAuth extends BaseAuth {
15
+ #private;
16
+ constructor(config: AuthConfig);
17
+ validate(): Promise<import("@nocobase/database").Model<any, any>>;
18
+ get dingTalkApi(): DingTalkApi;
19
+ get authConfigOptions(): AuthConfigOptions;
20
+ }
@@ -0,0 +1,135 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
9
+
10
+ var __defProp = Object.defineProperty;
11
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
12
+ var __getOwnPropNames = Object.getOwnPropertyNames;
13
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
14
+ var __export = (target, all) => {
15
+ for (var name in all)
16
+ __defProp(target, name, { get: all[name], enumerable: true });
17
+ };
18
+ var __copyProps = (to, from, except, desc) => {
19
+ if (from && typeof from === "object" || typeof from === "function") {
20
+ for (let key of __getOwnPropNames(from))
21
+ if (!__hasOwnProp.call(to, key) && key !== except)
22
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
23
+ }
24
+ return to;
25
+ };
26
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
27
+ var DingTalkAuth_exports = {};
28
+ __export(DingTalkAuth_exports, {
29
+ DingTalkAuth: () => DingTalkAuth
30
+ });
31
+ module.exports = __toCommonJS(DingTalkAuth_exports);
32
+ var import_auth = require("@nocobase/auth");
33
+ var import_dingTalkApi = require("../openapi/dingTalkApi");
34
+ class DingTalkAuth extends import_auth.BaseAuth {
35
+ #authConfigOptions;
36
+ #dingTalkApi;
37
+ constructor(config) {
38
+ var _a;
39
+ const userCollection = config.ctx.db.getCollection("users");
40
+ super({ ...config, userCollection });
41
+ this.#authConfigOptions = config.options;
42
+ this.#dingTalkApi = new import_dingTalkApi.DingTalkApi(this.#authConfigOptions.internal.appKey, this.#authConfigOptions.internal.appSecret);
43
+ this.#authConfigOptions = {
44
+ ...this.#authConfigOptions,
45
+ internal: {
46
+ userCheckType: this.#authConfigOptions.internal.userCheckType,
47
+ emailDomains: ((_a = config.options.internal.emailDomain) == null ? void 0 : _a.split("s*,s*")) || []
48
+ }
49
+ };
50
+ }
51
+ async validate() {
52
+ var _a, _b;
53
+ const ctx = this.ctx;
54
+ const { authenticator: authenticatorName, code, authCode, state } = ctx.action.params;
55
+ if (!authenticatorName) {
56
+ ctx.throw(400, "\u8BA4\u8BC1\u5668\u4E0D\u80FD\u4E3A\u7A7A");
57
+ }
58
+ if (!code) {
59
+ ctx.throw(400, "OAuth 2.0 \u4E34\u65F6\u6388\u6743\u7801\u4E0D\u5B58\u5728");
60
+ }
61
+ const auth = this;
62
+ const tokenRes = await auth.dingTalkApi.oauth2.userAccessToken("authorization_code", code);
63
+ const userRes = await auth.dingTalkApi.contact.getUser("me", tokenRes.accessToken);
64
+ const { userid: userId } = await auth.dingTalkApi.contact.getUserIdByUnionId(userRes.unionId);
65
+ const authenticator = this.authenticator;
66
+ let au = await authenticator.findUser(userId);
67
+ if (au) {
68
+ return au;
69
+ }
70
+ const userDetail = await auth.dingTalkApi.contact.getUserDetail(userId);
71
+ const user = {
72
+ userId,
73
+ unionId: userRes.unionId,
74
+ mobile: userRes.mobile,
75
+ email: userRes.email,
76
+ name: userDetail.name || userRes.nick,
77
+ orgEmail: userDetail.org_email
78
+ };
79
+ let filter;
80
+ if (this.#authConfigOptions.internal.userCheckType === "personalEmail") {
81
+ if (!user.email) {
82
+ ctx.throw(400, "\u7528\u6237\u90AE\u7BB1\u672A\u914D\u7F6E");
83
+ }
84
+ if (!this.#authConfigOptions.internal.emailDomains.some((a) => userDetail.email.endsWith(a))) {
85
+ ctx.throw(400, `\u90AE\u7BB1\u57DF\u540D\u672A\u542F\u7528 ${user.email}`);
86
+ }
87
+ filter = {
88
+ email: user.email
89
+ };
90
+ } else if (this.#authConfigOptions.internal.userCheckType === "orgEmail") {
91
+ if (!user.orgEmail) {
92
+ ctx.throw(400, "\u7528\u6237\u4F01\u4E1A\u90AE\u7BB1\u672A\u914D\u7F6E");
93
+ }
94
+ if (!this.#authConfigOptions.internal.emailDomains.some((a) => userDetail.org_email.endsWith(a))) {
95
+ ctx.throw(400, `\u90AE\u7BB1\u57DF\u540D\u672A\u542F\u7528 ${user.orgEmail}`);
96
+ }
97
+ filter = {
98
+ email: user.orgEmail
99
+ };
100
+ } else {
101
+ filter = {
102
+ phone: user.mobile
103
+ };
104
+ }
105
+ let ncUser = await this.userRepository.findOne({ filter });
106
+ if (ncUser) {
107
+ await this.authenticator.addUser(user, {
108
+ through: {
109
+ uuid: userId
110
+ }
111
+ });
112
+ return await authenticator.findUser(userId);
113
+ }
114
+ if (this.#authConfigOptions.public.autoSignup) {
115
+ return await authenticator.findOrCreateUser(userId, {
116
+ nickname: user.name,
117
+ username: ((_b = (_a = filter.email) == null ? void 0 : _a.split("@")) == null ? void 0 : _b[0]) || user.mobile || userId,
118
+ email: filter.email,
119
+ phone: user.mobile,
120
+ meta: JSON.stringify(user)
121
+ });
122
+ }
123
+ return null;
124
+ }
125
+ get dingTalkApi() {
126
+ return this.#dingTalkApi;
127
+ }
128
+ get authConfigOptions() {
129
+ return this.#authConfigOptions;
130
+ }
131
+ }
132
+ // Annotate the CommonJS export names for ESM import in node:
133
+ 0 && (module.exports = {
134
+ DingTalkAuth
135
+ });
@@ -0,0 +1,3 @@
1
+ export declare const PluginName = "community-ding-talk";
2
+ export declare const AuthName: string;
3
+ export declare const ResoureName = "community-ding-talk";
@@ -0,0 +1,42 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
9
+
10
+ var __defProp = Object.defineProperty;
11
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
12
+ var __getOwnPropNames = Object.getOwnPropertyNames;
13
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
14
+ var __export = (target, all) => {
15
+ for (var name in all)
16
+ __defProp(target, name, { get: all[name], enumerable: true });
17
+ };
18
+ var __copyProps = (to, from, except, desc) => {
19
+ if (from && typeof from === "object" || typeof from === "function") {
20
+ for (let key of __getOwnPropNames(from))
21
+ if (!__hasOwnProp.call(to, key) && key !== except)
22
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
23
+ }
24
+ return to;
25
+ };
26
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
27
+ var constants_exports = {};
28
+ __export(constants_exports, {
29
+ AuthName: () => AuthName,
30
+ PluginName: () => PluginName,
31
+ ResoureName: () => ResoureName
32
+ });
33
+ module.exports = __toCommonJS(constants_exports);
34
+ const PluginName = "community-ding-talk";
35
+ const AuthName = `${PluginName}-auth`;
36
+ const ResoureName = PluginName;
37
+ // Annotate the CommonJS export names for ESM import in node:
38
+ 0 && (module.exports = {
39
+ AuthName,
40
+ PluginName,
41
+ ResoureName
42
+ });
@@ -0,0 +1 @@
1
+ export { default } from './plugin';
@@ -0,0 +1,42 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
9
+
10
+ var __create = Object.create;
11
+ var __defProp = Object.defineProperty;
12
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
13
+ var __getOwnPropNames = Object.getOwnPropertyNames;
14
+ var __getProtoOf = Object.getPrototypeOf;
15
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
16
+ var __export = (target, all) => {
17
+ for (var name in all)
18
+ __defProp(target, name, { get: all[name], enumerable: true });
19
+ };
20
+ var __copyProps = (to, from, except, desc) => {
21
+ if (from && typeof from === "object" || typeof from === "function") {
22
+ for (let key of __getOwnPropNames(from))
23
+ if (!__hasOwnProp.call(to, key) && key !== except)
24
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
25
+ }
26
+ return to;
27
+ };
28
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
29
+ // If the importer is in node compatibility mode or this is not an ESM
30
+ // file that has been converted to a CommonJS file using a Babel-
31
+ // compatible transform (i.e. "__esModule" has not been set), then set
32
+ // "default" to the CommonJS "module.exports" for node compatibility.
33
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
34
+ mod
35
+ ));
36
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
37
+ var server_exports = {};
38
+ __export(server_exports, {
39
+ default: () => import_plugin.default
40
+ });
41
+ module.exports = __toCommonJS(server_exports);
42
+ var import_plugin = __toESM(require("./plugin"));
@@ -0,0 +1,99 @@
1
+ export type Res<T> = {
2
+ /** 请求ID。 */
3
+ request_id: string;
4
+ /** 返回码。 */
5
+ errcode: number;
6
+ /** 返回码描述。 */
7
+ errmsg: string;
8
+ /** 返回结果。 */
9
+ result: T;
10
+ };
11
+ export type UserAccessTokenRes = {
12
+ /** 生成的accessToken */
13
+ accessToken?: string;
14
+ /** 生成的refresh_token。可以使用此刷新token,定期的获取用户的accessToken */
15
+ refreshToken?: string;
16
+ /** 超时时间,单位秒。 */
17
+ expireIn?: number;
18
+ /** 所选企业corpId。 */
19
+ corpId?: string;
20
+ };
21
+ export type UserRes = {
22
+ /** 用户的钉钉昵称。 */
23
+ nick?: string;
24
+ /** 头像URL。 */
25
+ avatarUrl?: string;
26
+ /** 用户的手机号。如果要获取用户手机号,需要在钉钉开发者后台申请个人手机号信息权限 */
27
+ mobile?: string;
28
+ /** 用户的openId。 */
29
+ openId?: string;
30
+ /** 用户的unionId。 */
31
+ unionId?: string;
32
+ /** 用户的个人邮箱。 */
33
+ email?: string;
34
+ /** 手机号对应的国家号。 */
35
+ stateCode?: string;
36
+ };
37
+ export type UserDetail = {
38
+ /** 员工的userId。 */
39
+ userid: string;
40
+ /** 员工姓名。 */
41
+ name: string;
42
+ /** 员工邮箱。 */
43
+ email?: string;
44
+ /** 员工的企业邮箱。如果员工的企业邮箱没有开通,返回信息中不包含该数据。第三方企业应用不返回该参数。 */
45
+ org_email?: string;
46
+ };
47
+ export type UserId = {
48
+ /** 联系类型: 0:企业内部员工 1:企业外部联系人 */
49
+ contact_type?: number;
50
+ /** 用户的userid。 */
51
+ userid: string;
52
+ };
53
+ export declare function checkResult<T>(res: Res<T>): T;
54
+ /**
55
+ * 钉钉 API
56
+ */
57
+ export declare class DingTalkApi {
58
+ #private;
59
+ constructor(appKey: string, appSecret: string);
60
+ get oauth2(): {
61
+ /**
62
+ * 获取用户token
63
+ * @param grantType 如果使用授权码换token,传authorization_code。如果使用刷新token换用户token,传refresh_token。
64
+ * @param code OAuth 2.0 临时授权码,第三方企业应用需要接入统一授权套件/获取登录用户的访问凭证,获取临时授权码authCode。
65
+ * @param refreshToken OAuth2.0刷新令牌,从返回结果里面获取。过期时间是30天。
66
+ * @returns
67
+ */
68
+ userAccessToken(grantType: "authorization_code" | "refresh_token", code?: string, refreshToken?: string): Promise<UserAccessTokenRes>;
69
+ };
70
+ get contact(): {
71
+ /**
72
+ * 获取用户token
73
+ * @param unionId 用户的unionId。如需获取当前授权人的信息,unionId参数可以传me。
74
+ * @returns
75
+ */
76
+ getUser(unionId: string, accessToken: string): Promise<UserRes>;
77
+ /**
78
+ * 根据手机号查询用户ID
79
+ * @param mobile 用户的手机号。
80
+ * @returns 员工的userId。
81
+ */
82
+ getUserIdByMobile(mobile: string): Promise<UserId>;
83
+ /**
84
+ * 根据手机号查询用户ID
85
+ * @param unionid 员工在当前开发者企业账号范围内的唯一标识
86
+ * @returns 员工的userId。
87
+ */
88
+ getUserIdByUnionId(unionid: string): Promise<UserId>;
89
+ /**
90
+ * 查询用户详情
91
+ * @param userid 用户的userId。
92
+ * @returns 员工的userId。
93
+ */
94
+ getUserDetail(userid: string): Promise<UserDetail>;
95
+ };
96
+ getLoginUrl(redirectUri: string): string;
97
+ getAccessToken(): Promise<string>;
98
+ doRequest<T>(method: 'GET' | 'POST' | 'PUT' | 'DELETE', path: string, params?: any, body?: any, headers?: any): Promise<T>;
99
+ }
@@ -0,0 +1,178 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
9
+
10
+ var __defProp = Object.defineProperty;
11
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
12
+ var __getOwnPropNames = Object.getOwnPropertyNames;
13
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
14
+ var __export = (target, all) => {
15
+ for (var name in all)
16
+ __defProp(target, name, { get: all[name], enumerable: true });
17
+ };
18
+ var __copyProps = (to, from, except, desc) => {
19
+ if (from && typeof from === "object" || typeof from === "function") {
20
+ for (let key of __getOwnPropNames(from))
21
+ if (!__hasOwnProp.call(to, key) && key !== except)
22
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
23
+ }
24
+ return to;
25
+ };
26
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
27
+ var dingTalkApi_exports = {};
28
+ __export(dingTalkApi_exports, {
29
+ DingTalkApi: () => DingTalkApi,
30
+ checkResult: () => checkResult
31
+ });
32
+ module.exports = __toCommonJS(dingTalkApi_exports);
33
+ function checkResult(res) {
34
+ if (res.errcode !== 0) {
35
+ throw new Error(JSON.stringify(res));
36
+ }
37
+ return res.result;
38
+ }
39
+ class DingTalkApi {
40
+ /**
41
+ * 获取凭证
42
+ */
43
+ #oauth2 = /* @__PURE__ */ ((api) => {
44
+ const baseUrl = "https://api.dingtalk.com";
45
+ return {
46
+ /**
47
+ * 获取用户token
48
+ * @param grantType 如果使用授权码换token,传authorization_code。如果使用刷新token换用户token,传refresh_token。
49
+ * @param code OAuth 2.0 临时授权码,第三方企业应用需要接入统一授权套件/获取登录用户的访问凭证,获取临时授权码authCode。
50
+ * @param refreshToken OAuth2.0刷新令牌,从返回结果里面获取。过期时间是30天。
51
+ * @returns
52
+ */
53
+ async userAccessToken(grantType, code, refreshToken) {
54
+ return api.doRequest("POST", `${baseUrl}/v1.0/oauth2/userAccessToken`, null, {
55
+ clientId: api.#appKey,
56
+ clientSecret: api.#appSecret,
57
+ code,
58
+ refreshToken,
59
+ grantType
60
+ });
61
+ }
62
+ };
63
+ })(this);
64
+ /**
65
+ * 通讯录
66
+ */
67
+ #contact = /* @__PURE__ */ ((api) => {
68
+ const baseUrl = "https://api.dingtalk.com";
69
+ return {
70
+ /**
71
+ * 获取用户token
72
+ * @param unionId 用户的unionId。如需获取当前授权人的信息,unionId参数可以传me。
73
+ * @returns
74
+ */
75
+ async getUser(unionId, accessToken) {
76
+ return api.doRequest("GET", `${baseUrl}/v1.0/contact/users/${unionId}`, void 0, void 0, {
77
+ "x-acs-dingtalk-access-token": accessToken
78
+ });
79
+ },
80
+ /**
81
+ * 根据手机号查询用户ID
82
+ * @param mobile 用户的手机号。
83
+ * @returns 员工的userId。
84
+ */
85
+ async getUserIdByMobile(mobile) {
86
+ return checkResult(await api.doRequest("POST", `https://oapi.dingtalk.com/topapi/v2/user/getbymobile`, {
87
+ access_token: await api.getAccessToken()
88
+ }, {
89
+ mobile
90
+ }));
91
+ },
92
+ /**
93
+ * 根据手机号查询用户ID
94
+ * @param unionid 员工在当前开发者企业账号范围内的唯一标识
95
+ * @returns 员工的userId。
96
+ */
97
+ async getUserIdByUnionId(unionid) {
98
+ return checkResult(await api.doRequest("POST", `https://oapi.dingtalk.com/topapi/user/getbyunionid`, {
99
+ access_token: await api.getAccessToken()
100
+ }, {
101
+ unionid
102
+ }));
103
+ },
104
+ /**
105
+ * 查询用户详情
106
+ * @param userid 用户的userId。
107
+ * @returns 员工的userId。
108
+ */
109
+ async getUserDetail(userid) {
110
+ return checkResult(await api.doRequest("POST", `https://oapi.dingtalk.com/topapi/v2/user/get`, {
111
+ access_token: await api.getAccessToken()
112
+ }, {
113
+ userid
114
+ }));
115
+ }
116
+ };
117
+ })(this);
118
+ #appKey;
119
+ #appSecret;
120
+ #accessToken;
121
+ #nextGetAccessTokenTime;
122
+ constructor(appKey, appSecret) {
123
+ this.#appKey = appKey;
124
+ this.#appSecret = appSecret;
125
+ }
126
+ get oauth2() {
127
+ return this.#oauth2;
128
+ }
129
+ get contact() {
130
+ return this.#contact;
131
+ }
132
+ getLoginUrl(redirectUri) {
133
+ return `https://login.dingtalk.com/oauth2/auth?redirect_uri=${encodeURIComponent(redirectUri)}&response_type=code&client_id=${this.#appKey}&scope=openid&state=${(/* @__PURE__ */ new Date()).getTime()}&prompt=consent`;
134
+ }
135
+ async getAccessToken() {
136
+ if (!this.#accessToken || this.#nextGetAccessTokenTime < (/* @__PURE__ */ new Date()).getTime()) {
137
+ const data = await this.doRequest("POST", "https://api.dingtalk.com/v1.0/oauth2/accessToken", null, {
138
+ appKey: this.#appKey,
139
+ appSecret: this.#appSecret
140
+ });
141
+ this.#nextGetAccessTokenTime = (/* @__PURE__ */ new Date()).getTime() + data.expireIn * 1e3 - 1e5;
142
+ this.#accessToken = data.accessToken;
143
+ }
144
+ return this.#accessToken;
145
+ }
146
+ async doRequest(method, path, params, body, headers) {
147
+ const url = `${path}${params ? "?" + toQueryString(params) : ""}`;
148
+ const res = await fetch(url, {
149
+ method,
150
+ headers: {
151
+ "Content-Type": "application/json",
152
+ ...headers || {}
153
+ },
154
+ body: body ? JSON.stringify(body) : void 0
155
+ });
156
+ const r = {
157
+ method,
158
+ url,
159
+ headers,
160
+ params,
161
+ body
162
+ };
163
+ if (res.status < 200 || res.status >= 300) {
164
+ const text = await res.text();
165
+ console.error("fetch dingTalk api error: ", r, text);
166
+ throw new Error(text);
167
+ }
168
+ return await res.json();
169
+ }
170
+ }
171
+ function toQueryString(params) {
172
+ return Object.keys(params).map((key) => encodeURIComponent(key) + "=" + encodeURIComponent(params[key])).join("&");
173
+ }
174
+ // Annotate the CommonJS export names for ESM import in node:
175
+ 0 && (module.exports = {
176
+ DingTalkApi,
177
+ checkResult
178
+ });
@@ -0,0 +1,66 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
9
+
10
+ const typeMap = {
11
+ "LONG": "number",
12
+ "STRING": "string"
13
+ };
14
+ function apiToType(res) {
15
+ const reqBody = res.data.params.filter((a) => a.position === "BODY").map((a) => {
16
+ var _a;
17
+ return {
18
+ name: a.name,
19
+ desc: ((_a = a.desc) == null ? void 0 : _a.replaceAll("\n", " ")) || "",
20
+ required: a.required,
21
+ type: typeMap[a.type] || "any"
22
+ };
23
+ });
24
+ const resBody = res.data.rspParams.map((a) => {
25
+ var _a;
26
+ return {
27
+ name: a.name,
28
+ desc: ((_a = a.desc) == null ? void 0 : _a.replaceAll("\n", " ")) || "",
29
+ required: a.required,
30
+ type: typeMap[a.type] || "any"
31
+ };
32
+ });
33
+ const type = `
34
+ export type Req = {
35
+ ${reqBody.map((a) => ` /** ${a.desc} */
36
+ ${a.name}${a.required ? "" : "?"}: ${a.type};`).join("\n")}
37
+ }
38
+ export type Res = {
39
+ ${resBody.map((a) => ` /** ${a.desc} */
40
+ ${a.name}${a.required ? "" : "?"}: ${a.type};`).join("\n")}
41
+ }
42
+ async userAccessToken(taskId: number, projectId?: number) {
43
+ return api.doRequest<null>('POST', \`{baseUrl}/v1.0/oauth2/userAccessToken\`, null, {
44
+ clientId: this.#appKey,
45
+ clientSecret: this.#appSecret,
46
+ });
47
+ },
48
+ `;
49
+ return type;
50
+ }
51
+ async function genApiDetail(uuid, devType = "org") {
52
+ const fd = new FormData();
53
+ fd.append("uuid", uuid);
54
+ fd.append("devType", devType);
55
+ const res = await fetch("https://open-dev.dingtalk.com/openapi/explorer/getApiDetail", {
56
+ "headers": {},
57
+ "body": fd,
58
+ "method": "POST"
59
+ });
60
+ const data = await res.json();
61
+ return data;
62
+ }
63
+ (async () => {
64
+ const res = await genApiDetail("dingtalk.oapi.v2.user.get");
65
+ console.log(apiToType(res));
66
+ })();
@@ -0,0 +1,11 @@
1
+ import { Plugin } from '@nocobase/server';
2
+ export declare class NocobasePluginDingTalkServer extends Plugin {
3
+ afterAdd(): Promise<void>;
4
+ beforeLoad(): Promise<void>;
5
+ load(): Promise<void>;
6
+ install(): Promise<void>;
7
+ afterEnable(): Promise<void>;
8
+ afterDisable(): Promise<void>;
9
+ remove(): Promise<void>;
10
+ }
11
+ export default NocobasePluginDingTalkServer;
@@ -0,0 +1,66 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
9
+
10
+ var __defProp = Object.defineProperty;
11
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
12
+ var __getOwnPropNames = Object.getOwnPropertyNames;
13
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
14
+ var __export = (target, all) => {
15
+ for (var name in all)
16
+ __defProp(target, name, { get: all[name], enumerable: true });
17
+ };
18
+ var __copyProps = (to, from, except, desc) => {
19
+ if (from && typeof from === "object" || typeof from === "function") {
20
+ for (let key of __getOwnPropNames(from))
21
+ if (!__hasOwnProp.call(to, key) && key !== except)
22
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
23
+ }
24
+ return to;
25
+ };
26
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
27
+ var plugin_exports = {};
28
+ __export(plugin_exports, {
29
+ NocobasePluginDingTalkServer: () => NocobasePluginDingTalkServer,
30
+ default: () => plugin_default
31
+ });
32
+ module.exports = __toCommonJS(plugin_exports);
33
+ var import_server = require("@nocobase/server");
34
+ var import_DingTalkAuth = require("./auth/DingTalkAuth");
35
+ var import_dingTalkActions = require("./actions/dingTalkActions");
36
+ var import_constants = require("./constants");
37
+ class NocobasePluginDingTalkServer extends import_server.Plugin {
38
+ async afterAdd() {
39
+ }
40
+ async beforeLoad() {
41
+ }
42
+ async load() {
43
+ this.app.authManager.registerTypes(import_constants.AuthName, {
44
+ title: "\u9489\u9489\u767B\u5F55(\u793E\u533A)",
45
+ auth: import_DingTalkAuth.DingTalkAuth
46
+ });
47
+ this.app.resourceManager.define({
48
+ name: import_constants.ResoureName,
49
+ actions: import_dingTalkActions.dingTalkActions
50
+ });
51
+ this.app.acl.allow(import_constants.ResoureName, "*");
52
+ }
53
+ async install() {
54
+ }
55
+ async afterEnable() {
56
+ }
57
+ async afterDisable() {
58
+ }
59
+ async remove() {
60
+ }
61
+ }
62
+ var plugin_default = NocobasePluginDingTalkServer;
63
+ // Annotate the CommonJS export names for ESM import in node:
64
+ 0 && (module.exports = {
65
+ NocobasePluginDingTalkServer
66
+ });
package/package.json ADDED
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "@yeclimeric/nocobase-plugin-dingtalk",
3
+ "version": "1.9.1",
4
+ "displayName": "DingTalk",
5
+ "displayName.zh-CN": "钉钉登录",
6
+ "description": "Integrated DingTalk login function",
7
+ "description.zh-CN": "集成钉钉登录功能",
8
+ "keywords": [
9
+ "plugin",
10
+ "钉钉",
11
+ "dingding",
12
+ "dingtalk",
13
+ "nocobase"
14
+ ],
15
+ "author": {
16
+ "name": "不就订个外卖么",
17
+ "email": "yeclimeric@gmail.com"
18
+ },
19
+ "main": "dist/server/index.js",
20
+ "files": [
21
+ "CHANGELOG.md",
22
+ "dist/**"
23
+ ],
24
+ "dependencies": {},
25
+ "peerDependencies": {
26
+ "@nocobase/client": "1.x",
27
+ "@nocobase/server": "1.x",
28
+ "@nocobase/test": "1.x"
29
+ }
30
+ }