@nocobase/plugin-idp-oauth 2.1.0-alpha.40 → 2.1.0-alpha.45

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.
@@ -7,4 +7,4 @@
7
7
  * For more information, please refer to: https://www.nocobase.com/agreement.
8
8
  */
9
9
 
10
- !function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("antd"),require("react"),require("@nocobase/client"),require("react-router-dom")):"function"==typeof define&&define.amd?define("@nocobase/plugin-idp-oauth",["antd","react","@nocobase/client","react-router-dom"],t):"object"==typeof exports?exports["@nocobase/plugin-idp-oauth"]=t(require("antd"),require("react"),require("@nocobase/client"),require("react-router-dom")):e["@nocobase/plugin-idp-oauth"]=t(e.antd,e.react,e["@nocobase/client"],e["react-router-dom"])}(self,function(e,t,r,n){return function(){"use strict";var o={342:function(e){e.exports=r},59:function(t){t.exports=e},155:function(e){e.exports=t},442:function(e){e.exports=n}},i={};function a(e){var t=i[e];if(void 0!==t)return t.exports;var r=i[e]={exports:{}};return o[e](r,r.exports,a),r.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 r in t)a.o(t,r)&&!a.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},a.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||Function("return this")()}catch(e){if("object"==typeof window)return window}}(),a.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},a.r=function(e){"u">typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},a.g.importScripts&&(u=a.g.location+"");var u,c=a.g.document;if(!u&&c&&(c.currentScript&&"SCRIPT"===c.currentScript.tagName.toUpperCase()&&(u=c.currentScript.src),!u)){var l=c.getElementsByTagName("script");if(l.length)for(var s=l.length-1;s>-1&&(!u||!/^http(s?):/.test(u));)u=l[s--].src}if(!u)throw Error("Automatic publicPath is not supported in this browser");a.p=u.replace(/^blob:/,"").replace(/#.*$/,"").replace(/\?.*$/,"").replace(/\/[^\/]+$/,"/");var p={};return!function(){var e="",t="u">typeof document?document.currentScript:null;if(t&&t.src&&(e=t.src.replace(/^blob:/,"").replace(/#.*$/,"").replace(/\?.*$/,"").replace(/\/[^\/]+$/,"/")),!e){var r=window.__webpack_public_path__||"";r&&("/"!==r.charAt(r.length-1)&&(r+="/"),e=r+"static/plugins/@nocobase/plugin-idp-oauth/dist/client/")}if(!e){if(!(e=window.__nocobase_public_path__||"")&&window.location&&window.location.pathname){var n=window.location.pathname||"/",o=n.indexOf("/v2/");e=o>=0?n.slice(0,o+1):"/"}e&&(e=e.replace(/\/v2\/?$/,"/")),e||(e="/"),"/"!==e.charAt(e.length-1)&&(e+="/"),e+="static/plugins/@nocobase/plugin-idp-oauth/dist/client/"}a.p=e}(),!function(){a.r(p),a.d(p,{default:function(){return O}});var e=a(342),t=a(59),r=a(155),n=a.n(r),o=a(442);function i(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=Array(t);r<t;r++)n[r]=e[r];return n}var u=function(){var e,r=(function(e){if(Array.isArray(e))return e}(e=(0,o.useSearchParams)())||function(e){var t,r,n=null==e?null:"u">typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=n){var o=[],i=!0,a=!1;try{for(n=n.call(e);!(i=(t=n.next()).done)&&(o.push(t.value),1!==o.length);i=!0);}catch(e){a=!0,r=e}finally{try{i||null==n.return||n.return()}finally{if(a)throw r}}return o}}(e)||function(e){if(e){if("string"==typeof e)return i(e,1);var t=Object.prototype.toString.call(e).slice(8,-1);if("Object"===t&&e.constructor&&(t=e.constructor.name),"Map"===t||"Set"===t)return Array.from(t);if("Arguments"===t||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t))return i(e,1)}}(e)||function(){throw TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}())[0],a=r.get("error"),u=r.get("error_description"),c=r.get("iss");return n().createElement("div",{style:{maxWidth:640,margin:"48px auto",padding:"0 24px"}},n().createElement(t.Result,{status:"error",title:a||"Authentication failed",subTitle:u||void 0}),n().createElement(t.Space,{direction:"vertical",size:"middle",style:{width:"100%"}},c?n().createElement("div",null,n().createElement(t.Typography.Text,{type:"secondary"},"Issuer"),n().createElement("div",null,n().createElement(t.Typography.Text,{code:!0},c))):null))};function c(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=Array(t);r<t;r++)n[r]=e[r];return n}function l(e,t,r,n,o,i,a){try{var u=e[i](a),c=u.value}catch(e){r(e);return}u.done?t(c):Promise.resolve(c).then(n,o)}function s(e){return function(){var t=this,r=arguments;return new Promise(function(n,o){var i=e.apply(t,r);function a(e){l(i,n,o,a,u,"next",e)}function u(e){l(i,n,o,a,u,"throw",e)}a(void 0)})}}function f(e,t){return null!=t&&"u">typeof Symbol&&t[Symbol.hasInstance]?!!t[Symbol.hasInstance](e):e instanceof t}function d(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var r,n,o=null==e?null:"u">typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=o){var i=[],a=!0,u=!1;try{for(o=o.call(e);!(a=(r=o.next()).done)&&(i.push(r.value),!t||i.length!==t);a=!0);}catch(e){u=!0,n=e}finally{try{a||null==o.return||o.return()}finally{if(u)throw n}}return i}}(e,t)||function(e,t){if(e){if("string"==typeof e)return c(e,t);var r=Object.prototype.toString.call(e).slice(8,-1);if("Object"===r&&e.constructor&&(r=e.constructor.name),"Map"===r||"Set"===r)return Array.from(r);if("Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r))return c(e,t)}}(e,t)||function(){throw TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function y(e,t){var r,n,o,i={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]},a=Object.create(("function"==typeof Iterator?Iterator:Object).prototype),u=Object.defineProperty;return u(a,"next",{value:c(0)}),u(a,"throw",{value:c(1)}),u(a,"return",{value:c(2)}),"function"==typeof Symbol&&u(a,Symbol.iterator,{value:function(){return this}}),a;function c(u){return function(c){var l=[u,c];if(r)throw TypeError("Generator is already executing.");for(;a&&(a=0,l[0]&&(i=0)),i;)try{if(r=1,n&&(o=2&l[0]?n.return:l[0]?n.throw||((o=n.return)&&o.call(n),0):n.next)&&!(o=o.call(n,l[1])).done)return o;switch(n=0,o&&(l=[2&l[0],o.value]),l[0]){case 0:case 1:o=l;break;case 4:return i.label++,{value:l[1],done:!1};case 5:i.label++,n=l[1],l=[0];continue;case 7:l=i.ops.pop(),i.trys.pop();continue;default:if(!(o=(o=i.trys).length>0&&o[o.length-1])&&(6===l[0]||2===l[0])){i=0;continue}if(3===l[0]&&(!o||l[1]>o[0]&&l[1]<o[3])){i.label=l[1];break}if(6===l[0]&&i.label<o[1]){i.label=o[1],o=l;break}if(o&&i.label<o[2]){i.label=o[2],i.ops.push(l);break}o[2]&&i.ops.pop(),i.trys.pop();continue}l=t.call(e,i)}catch(e){l=[6,e],n=0}finally{r=o=0}if(5&l[0])throw l[1];return{value:l[0]?l[1]:void 0,done:!0}}}}function h(e,t){return f(e,Error)?e.message:t}var m=function(){var i=(0,e.useAPIClient)(),a=(0,e.useApp)(),u=(0,o.useNavigate)(),c=(0,o.useParams)(),l=d((0,r.useState)(!0),2),p=l[0],m=l[1],b=d((0,r.useState)(null),2),v=b[0],g=b[1],w=d((0,r.useState)(null),2),E=w[0],x=w[1],S=(0,r.useMemo)(function(){return c.uid?"main"===a.name?"idpOAuth/interaction/".concat(c.uid):"__app/".concat(a.name,"/idpOAuth/interaction/").concat(c.uid):null},[a.name,c.uid]),O=(0,r.useMemo)(function(){return c.uid?"/idp-oauth/interaction/".concat(c.uid):"/signin"},[c.uid]),j=(0,r.useCallback)(function(e,t){return s(function(){var r,n,o,a,c;return y(this,function(l){switch(l.label){case 0:if(!S)return g("Invalid interaction path"),m(!1),[2];return n=i.auth.getToken(),o=i.auth.getAuthenticator()||"basic",[4,i.request({url:S,method:e,skipNotify:!0,withCredentials:!0,data:"post"===e?t:void 0,headers:n?{Authorization:"Bearer ".concat(n),"X-Authenticator":o}:void 0})];case 1:if(null==(c=(null==(a=l.sent())||null==(r=a.data)?void 0:r.data)||(null==a?void 0:a.data))?void 0:c.redirectTo)return window.location.replace(c.redirectTo),[2];if((null==c?void 0:c.prompt)!=="login")return[3,4];if(!n)return u("/signin?redirect=".concat(encodeURIComponent(O)),{replace:!0}),[2];if("get"!==e)return[3,3];return[4,j("post")];case 2:return l.sent(),[2];case 3:return u("/signin?redirect=".concat(encodeURIComponent(O)),{replace:!0}),[2];case 4:return x(c),m(!1),[2]}})})()},[i,O,S,u]),A=(0,r.useCallback)(function(){var e=arguments.length>0&&void 0!==arguments[0]&&arguments[0];return s(function(){return y(this,function(t){switch(t.label){case 0:m(!0),g(null),t.label=1;case 1:return t.trys.push([1,3,,4]),[4,j("post",e?{cancel:1}:{submit:1})];case 2:return t.sent(),[3,4];case 3:return g(h(t.sent(),"Failed to submit interaction")),m(!1),[3,4];case 4:return[2]}})})()},[j]);return((0,r.useEffect)(function(){var e=!1;return s(function(){var t;return y(this,function(r){switch(r.label){case 0:return r.trys.push([0,2,,3]),[4,j("get")];case 1:return r.sent(),[3,3];case 2:return t=r.sent(),e||(g(h(t,"Failed to load interaction")),m(!1)),[3,3];case 3:return[2]}})})(),function(){e=!0}},[j]),(0,r.useEffect)(function(){if((null==E?void 0:E.prompt)==="consent"&&!p){var e=function(e){if(!e.defaultPrevented){var t=e.target;if(null==t||!t.closest('input, textarea, select, [contenteditable="true"]')){if("Enter"===e.key&&!e.shiftKey&&!e.ctrlKey&&!e.metaKey&&!e.altKey){var r=document.activeElement;if(f(r,HTMLButtonElement)||f(r,HTMLAnchorElement))return;e.preventDefault(),A(!1);return}"Escape"===e.key&&(e.preventDefault(),A(!0))}}};return window.addEventListener("keydown",e),function(){return window.removeEventListener("keydown",e)}}},[null==E?void 0:E.prompt,p,A]),p)?n().createElement("div",{style:{display:"flex",justifyContent:"center",padding:48}},n().createElement(t.Spin,{size:"large"})):v?n().createElement("div",{style:{maxWidth:640,margin:"48px auto",padding:"0 24px"}},n().createElement(t.Alert,{type:"error",message:v,showIcon:!0})):(null==E?void 0:E.prompt)==="consent"?n().createElement("div",{style:{maxWidth:640,margin:"48px auto",padding:"0 24px"}},n().createElement(t.Card,null,n().createElement(t.Space,{direction:"vertical",size:"large",style:{width:"100%"}},n().createElement("div",null,n().createElement(t.Typography.Title,{level:3,style:{marginBottom:8}},"Authorize application"),n().createElement(t.Typography.Paragraph,{style:{marginBottom:0}},E.clientName||"Application"," requests access to your account.")),E.details?n().createElement(t.Alert,{type:"info",showIcon:!0,message:"Requested permissions",description:E.details}):null,n().createElement(t.Space,null,n().createElement(t.Button,{type:"primary",loading:p,onClick:function(){return A(!1)}},"Continue"),n().createElement(t.Button,{loading:p,onClick:function(){return A(!0)}},"Cancel"))))):n().createElement("div",{style:{maxWidth:640,margin:"48px auto",padding:"0 24px"}},n().createElement(t.Result,{title:"Redirecting...",subTitle:"Please wait while authorization continues."}))},b={};function v(e,t,r,n,o,i,a){try{var u=e[i](a),c=u.value}catch(e){r(e);return}u.done?t(c):Promise.resolve(c).then(n,o)}function g(e,t,r){return(g=S()?Reflect.construct:function(e,t,r){var n=[null];n.push.apply(n,t);var o=new(Function.bind.apply(e,n));return r&&E(o,r.prototype),o}).apply(null,arguments)}function w(e){return(w=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)})(e)}function E(e,t){return(E=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e})(e,t)}function x(e){var t="function"==typeof Map?new Map:void 0;return(x=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,r)}function r(){return g(e,arguments,w(this).constructor)}return r.prototype=Object.create(e.prototype,{constructor:{value:r,enumerable:!1,writable:!0,configurable:!0}}),E(r,e)})(e)}function S(){try{var e=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){}))}catch(e){}return(S=function(){return!!e})()}var O=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=w(e),function(e,t){var r;if(t&&("object"==((r=t)&&"u">typeof Symbol&&r.constructor===Symbol?"symbol":typeof r)||"function"==typeof t))return t;if(void 0===e)throw ReferenceError("this hasn't been initialised - super() hasn't been called");return e}(this,S()?Reflect.construct(e,t||[],w(this).constructor):e.apply(this,t))}return r.prototype=Object.create(e&&e.prototype,{constructor:{value:r,writable:!0,configurable:!0}}),e&&E(r,e),t=[{key:"load",value:function(){var e;return(e=function(){return function(e,t){var r,n,o,i={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]},a=Object.create(("function"==typeof Iterator?Iterator:Object).prototype),u=Object.defineProperty;return u(a,"next",{value:c(0)}),u(a,"throw",{value:c(1)}),u(a,"return",{value:c(2)}),"function"==typeof Symbol&&u(a,Symbol.iterator,{value:function(){return this}}),a;function c(u){return function(c){var l=[u,c];if(r)throw TypeError("Generator is already executing.");for(;a&&(a=0,l[0]&&(i=0)),i;)try{if(r=1,n&&(o=2&l[0]?n.return:l[0]?n.throw||((o=n.return)&&o.call(n),0):n.next)&&!(o=o.call(n,l[1])).done)return o;switch(n=0,o&&(l=[2&l[0],o.value]),l[0]){case 0:case 1:o=l;break;case 4:return i.label++,{value:l[1],done:!1};case 5:i.label++,n=l[1],l=[0];continue;case 7:l=i.ops.pop(),i.trys.pop();continue;default:if(!(o=(o=i.trys).length>0&&o[o.length-1])&&(6===l[0]||2===l[0])){i=0;continue}if(3===l[0]&&(!o||l[1]>o[0]&&l[1]<o[3])){i.label=l[1];break}if(6===l[0]&&i.label<o[1]){i.label=o[1],o=l;break}if(o&&i.label<o[2]){i.label=o[2],i.ops.push(l);break}o[2]&&i.ops.pop(),i.trys.pop();continue}l=t.call(e,i)}catch(e){l=[6,e],n=0}finally{r=o=0}if(5&l[0])throw l[1];return{value:l[0]?l[1]:void 0,done:!0}}}}(this,function(e){return this.flowEngine.registerModels(b),this.router.add("idp-oauth.interaction",{path:"/idp-oauth/interaction/:uid",Component:m,skipAuthCheck:!0}),this.router.add("idp-oauth.error",{path:"/idp-oauth/error",Component:u,skipAuthCheck:!0}),[2]})},function(){var t=this,r=arguments;return new Promise(function(n,o){var i=e.apply(t,r);function a(e){v(i,n,o,a,u,"next",e)}function u(e){v(i,n,o,a,u,"throw",e)}a(void 0)})}).call(this)}}],function(e,t){for(var r=0;r<t.length;r++){var n=t[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,n.key,n)}}(r.prototype,t),r}(x(e.Plugin))}(),p}()});
10
+ !function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("antd"),require("react"),require("@nocobase/client"),require("react-router-dom")):"function"==typeof define&&define.amd?define("@nocobase/plugin-idp-oauth",["antd","react","@nocobase/client","react-router-dom"],t):"object"==typeof exports?exports["@nocobase/plugin-idp-oauth"]=t(require("antd"),require("react"),require("@nocobase/client"),require("react-router-dom")):e["@nocobase/plugin-idp-oauth"]=t(e.antd,e.react,e["@nocobase/client"],e["react-router-dom"])}(self,function(e,t,r,n){return function(){"use strict";var o={342:function(e){e.exports=r},59:function(t){t.exports=e},155:function(e){e.exports=t},442:function(e){e.exports=n}},i={};function a(e){var t=i[e];if(void 0!==t)return t.exports;var r=i[e]={exports:{}};return o[e](r,r.exports,a),r.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 r in t)a.o(t,r)&&!a.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},a.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||Function("return this")()}catch(e){if("object"==typeof window)return window}}(),a.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},a.r=function(e){"u">typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},a.g.importScripts&&(u=a.g.location+"");var u,c=a.g.document;if(!u&&c&&(c.currentScript&&"SCRIPT"===c.currentScript.tagName.toUpperCase()&&(u=c.currentScript.src),!u)){var l=c.getElementsByTagName("script");if(l.length)for(var s=l.length-1;s>-1&&(!u||!/^http(s?):/.test(u));)u=l[s--].src}if(!u)throw Error("Automatic publicPath is not supported in this browser");a.p=u.replace(/^blob:/,"").replace(/#.*$/,"").replace(/\?.*$/,"").replace(/\/[^\/]+$/,"/");var p={};return!function(){var e="",t="u">typeof document?document.currentScript:null;if(t&&t.src&&(e=t.src.replace(/^blob:/,"").replace(/#.*$/,"").replace(/\?.*$/,"").replace(/\/[^\/]+$/,"/")),!e){var r=window.__webpack_public_path__||"";r&&("/"!==r.charAt(r.length-1)&&(r+="/"),e=r+"static/plugins/@nocobase/plugin-idp-oauth/dist/client/")}if(!e){if(!(e=window.__nocobase_public_path__||"")&&window.location&&window.location.pathname){var n=window.location.pathname||"/",o=n.indexOf("/v2/");e=o>=0?n.slice(0,o+1):"/"}e&&(e=e.replace(/\/v2\/?$/,"/")),e||(e="/"),"/"!==e.charAt(e.length-1)&&(e+="/"),e+="static/plugins/@nocobase/plugin-idp-oauth/dist/client/"}a.p=e}(),!function(){a.r(p),a.d(p,{default:function(){return O}});var e=a(342),t=a(59),r=a(155),n=a.n(r),o=a(442);function i(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=Array(t);r<t;r++)n[r]=e[r];return n}var u=function(){var e,r=(function(e){if(Array.isArray(e))return e}(e=(0,o.useSearchParams)())||function(e){var t,r,n=null==e?null:"u">typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=n){var o=[],i=!0,a=!1;try{for(n=n.call(e);!(i=(t=n.next()).done)&&(o.push(t.value),1!==o.length);i=!0);}catch(e){a=!0,r=e}finally{try{i||null==n.return||n.return()}finally{if(a)throw r}}return o}}(e)||function(e){if(e){if("string"==typeof e)return i(e,1);var t=Object.prototype.toString.call(e).slice(8,-1);if("Object"===t&&e.constructor&&(t=e.constructor.name),"Map"===t||"Set"===t)return Array.from(t);if("Arguments"===t||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t))return i(e,1)}}(e)||function(){throw TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}())[0],a=r.get("error"),u=r.get("error_description"),c=r.get("iss");return n().createElement("div",{style:{maxWidth:640,margin:"48px auto",padding:"0 24px"}},n().createElement(t.Result,{status:"error",title:a||"Authentication failed",subTitle:u||void 0}),n().createElement(t.Space,{direction:"vertical",size:"middle",style:{width:"100%"}},c?n().createElement("div",null,n().createElement(t.Typography.Text,{type:"secondary"},"Issuer"),n().createElement("div",null,n().createElement(t.Typography.Text,{code:!0},c))):null))};function c(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=Array(t);r<t;r++)n[r]=e[r];return n}function l(e,t,r,n,o,i,a){try{var u=e[i](a),c=u.value}catch(e){r(e);return}u.done?t(c):Promise.resolve(c).then(n,o)}function s(e){return function(){var t=this,r=arguments;return new Promise(function(n,o){var i=e.apply(t,r);function a(e){l(i,n,o,a,u,"next",e)}function u(e){l(i,n,o,a,u,"throw",e)}a(void 0)})}}function f(e,t){return null!=t&&"u">typeof Symbol&&t[Symbol.hasInstance]?!!t[Symbol.hasInstance](e):e instanceof t}function d(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var r,n,o=null==e?null:"u">typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=o){var i=[],a=!0,u=!1;try{for(o=o.call(e);!(a=(r=o.next()).done)&&(i.push(r.value),!t||i.length!==t);a=!0);}catch(e){u=!0,n=e}finally{try{a||null==o.return||o.return()}finally{if(u)throw n}}return i}}(e,t)||function(e,t){if(e){if("string"==typeof e)return c(e,t);var r=Object.prototype.toString.call(e).slice(8,-1);if("Object"===r&&e.constructor&&(r=e.constructor.name),"Map"===r||"Set"===r)return Array.from(r);if("Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r))return c(e,t)}}(e,t)||function(){throw TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function y(e,t){var r,n,o,i={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]},a=Object.create(("function"==typeof Iterator?Iterator:Object).prototype),u=Object.defineProperty;return u(a,"next",{value:c(0)}),u(a,"throw",{value:c(1)}),u(a,"return",{value:c(2)}),"function"==typeof Symbol&&u(a,Symbol.iterator,{value:function(){return this}}),a;function c(u){return function(c){var l=[u,c];if(r)throw TypeError("Generator is already executing.");for(;a&&(a=0,l[0]&&(i=0)),i;)try{if(r=1,n&&(o=2&l[0]?n.return:l[0]?n.throw||((o=n.return)&&o.call(n),0):n.next)&&!(o=o.call(n,l[1])).done)return o;switch(n=0,o&&(l=[2&l[0],o.value]),l[0]){case 0:case 1:o=l;break;case 4:return i.label++,{value:l[1],done:!1};case 5:i.label++,n=l[1],l=[0];continue;case 7:l=i.ops.pop(),i.trys.pop();continue;default:if(!(o=(o=i.trys).length>0&&o[o.length-1])&&(6===l[0]||2===l[0])){i=0;continue}if(3===l[0]&&(!o||l[1]>o[0]&&l[1]<o[3])){i.label=l[1];break}if(6===l[0]&&i.label<o[1]){i.label=o[1],o=l;break}if(o&&i.label<o[2]){i.label=o[2],i.ops.push(l);break}o[2]&&i.ops.pop(),i.trys.pop();continue}l=t.call(e,i)}catch(e){l=[6,e],n=0}finally{r=o=0}if(5&l[0])throw l[1];return{value:l[0]?l[1]:void 0,done:!0}}}}function h(e,t){return f(e,Error)?e.message:t}var m=function(){var i=(0,e.useAPIClient)(),a=(0,e.useApp)(),u=(0,o.useNavigate)(),c=(0,o.useParams)(),l=d((0,r.useState)(!0),2),p=l[0],m=l[1],v=d((0,r.useState)(null),2),b=v[0],g=v[1],w=d((0,r.useState)(null),2),E=w[0],x=w[1],S=(0,r.useMemo)(function(){return c.uid?"main"===a.name?"idpOAuth/interaction/".concat(c.uid):"__app/".concat(a.name,"/idpOAuth/interaction/").concat(c.uid):null},[a.name,c.uid]),O=(0,r.useMemo)(function(){return c.uid?"/idp-oauth/interaction/".concat(c.uid):"/signin"},[c.uid]),j=(0,r.useCallback)(function(e,t){return s(function(){var r,n,o,a,c;return y(this,function(l){switch(l.label){case 0:if(!S)return g("Invalid interaction path"),m(!1),[2];return n=i.auth.getToken(),o=i.auth.getAuthenticator()||"basic",[4,i.request({url:S,method:e,skipNotify:!0,withCredentials:!0,data:"post"===e?t:void 0,headers:n?{Authorization:"Bearer ".concat(n),"X-Authenticator":o}:void 0})];case 1:if(null==(c=(null==(a=l.sent())||null==(r=a.data)?void 0:r.data)||(null==a?void 0:a.data))?void 0:c.redirectTo)return window.location.replace(c.redirectTo),[2];if((null==c?void 0:c.prompt)!=="login")return[3,4];if(!n)return u("/signin?redirect=".concat(encodeURIComponent(O)),{replace:!0}),[2];if("get"!==e)return[3,3];return[4,j("post")];case 2:return l.sent(),[2];case 3:return u("/signin?redirect=".concat(encodeURIComponent(O)),{replace:!0}),[2];case 4:return x(c),m(!1),[2]}})})()},[i,O,S,u]),A=(0,r.useCallback)(function(){var e=arguments.length>0&&void 0!==arguments[0]&&arguments[0];return s(function(){return y(this,function(t){switch(t.label){case 0:m(!0),g(null),t.label=1;case 1:return t.trys.push([1,3,,4]),[4,j("post",e?{cancel:1}:{submit:1})];case 2:return t.sent(),[3,4];case 3:return g(h(t.sent(),"Failed to submit interaction")),m(!1),[3,4];case 4:return[2]}})})()},[j]);return((0,r.useEffect)(function(){var e=!1;return s(function(){var t;return y(this,function(r){switch(r.label){case 0:return r.trys.push([0,2,,3]),[4,j("get")];case 1:return r.sent(),[3,3];case 2:return t=r.sent(),e||(g(h(t,"Failed to load interaction")),m(!1)),[3,3];case 3:return[2]}})})(),function(){e=!0}},[j]),(0,r.useEffect)(function(){if((null==E?void 0:E.prompt)==="consent"&&!p){var e=function(e){if(!e.defaultPrevented){var t=e.target;if(null==t||!t.closest('input, textarea, select, [contenteditable="true"]')){if("Enter"===e.key&&!e.shiftKey&&!e.ctrlKey&&!e.metaKey&&!e.altKey){var r=document.activeElement;if(f(r,HTMLButtonElement)||f(r,HTMLAnchorElement))return;e.preventDefault(),A(!1);return}"Escape"===e.key&&(e.preventDefault(),A(!0))}}};return window.addEventListener("keydown",e),function(){return window.removeEventListener("keydown",e)}}},[null==E?void 0:E.prompt,p,A]),p)?n().createElement("div",{style:{position:"fixed",inset:0,display:"flex",alignItems:"center",justifyContent:"center"}},n().createElement(t.Spin,{style:{fontSize:72}})):b?n().createElement("div",{style:{maxWidth:640,margin:"48px auto",padding:"0 24px"}},n().createElement(t.Alert,{type:"error",message:b,showIcon:!0})):(null==E?void 0:E.prompt)==="consent"?n().createElement("div",{style:{maxWidth:640,margin:"48px auto",padding:"0 24px"}},n().createElement(t.Card,null,n().createElement(t.Space,{direction:"vertical",size:"large",style:{width:"100%"}},n().createElement("div",null,n().createElement(t.Typography.Title,{level:3,style:{marginBottom:8}},"Authorize application"),n().createElement(t.Typography.Paragraph,{style:{marginBottom:0}},E.clientName||"Application"," requests access to your account.")),E.details?n().createElement(t.Alert,{type:"info",showIcon:!0,message:"Requested permissions",description:E.details}):null,n().createElement(t.Space,null,n().createElement(t.Button,{type:"primary",loading:p,onClick:function(){return A(!1)}},"Continue"),n().createElement(t.Button,{loading:p,onClick:function(){return A(!0)}},"Cancel"))))):n().createElement("div",{style:{maxWidth:640,margin:"48px auto",padding:"0 24px"}},n().createElement(t.Result,{title:"Redirecting...",subTitle:"Please wait while authorization continues."}))},v={};function b(e,t,r,n,o,i,a){try{var u=e[i](a),c=u.value}catch(e){r(e);return}u.done?t(c):Promise.resolve(c).then(n,o)}function g(e,t,r){return(g=S()?Reflect.construct:function(e,t,r){var n=[null];n.push.apply(n,t);var o=new(Function.bind.apply(e,n));return r&&E(o,r.prototype),o}).apply(null,arguments)}function w(e){return(w=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)})(e)}function E(e,t){return(E=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e})(e,t)}function x(e){var t="function"==typeof Map?new Map:void 0;return(x=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,r)}function r(){return g(e,arguments,w(this).constructor)}return r.prototype=Object.create(e.prototype,{constructor:{value:r,enumerable:!1,writable:!0,configurable:!0}}),E(r,e)})(e)}function S(){try{var e=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){}))}catch(e){}return(S=function(){return!!e})()}var O=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=w(e),function(e,t){var r;if(t&&("object"==((r=t)&&"u">typeof Symbol&&r.constructor===Symbol?"symbol":typeof r)||"function"==typeof t))return t;if(void 0===e)throw ReferenceError("this hasn't been initialised - super() hasn't been called");return e}(this,S()?Reflect.construct(e,t||[],w(this).constructor):e.apply(this,t))}return r.prototype=Object.create(e&&e.prototype,{constructor:{value:r,writable:!0,configurable:!0}}),e&&E(r,e),t=[{key:"load",value:function(){var e;return(e=function(){var e;return function(e,t){var r,n,o,i={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]},a=Object.create(("function"==typeof Iterator?Iterator:Object).prototype),u=Object.defineProperty;return u(a,"next",{value:c(0)}),u(a,"throw",{value:c(1)}),u(a,"return",{value:c(2)}),"function"==typeof Symbol&&u(a,Symbol.iterator,{value:function(){return this}}),a;function c(u){return function(c){var l=[u,c];if(r)throw TypeError("Generator is already executing.");for(;a&&(a=0,l[0]&&(i=0)),i;)try{if(r=1,n&&(o=2&l[0]?n.return:l[0]?n.throw||((o=n.return)&&o.call(n),0):n.next)&&!(o=o.call(n,l[1])).done)return o;switch(n=0,o&&(l=[2&l[0],o.value]),l[0]){case 0:case 1:o=l;break;case 4:return i.label++,{value:l[1],done:!1};case 5:i.label++,n=l[1],l=[0];continue;case 7:l=i.ops.pop(),i.trys.pop();continue;default:if(!(o=(o=i.trys).length>0&&o[o.length-1])&&(6===l[0]||2===l[0])){i=0;continue}if(3===l[0]&&(!o||l[1]>o[0]&&l[1]<o[3])){i.label=l[1];break}if(6===l[0]&&i.label<o[1]){i.label=o[1],o=l;break}if(o&&i.label<o[2]){i.label=o[2],i.ops.push(l);break}o[2]&&i.ops.pop(),i.trys.pop();continue}l=t.call(e,i)}catch(e){l=[6,e],n=0}finally{r=o=0}if(5&l[0])throw l[1];return{value:l[0]?l[1]:void 0,done:!0}}}}(this,function(t){return e=this,e.flowEngine.registerModels(v),e.router.add("idp-oauth.interaction",{path:"/idp-oauth/interaction/:uid",Component:m,skipAuthCheck:!0}),e.router.add("idp-oauth.error",{path:"/idp-oauth/error",Component:u,skipAuthCheck:!0}),[2]})},function(){var t=this,r=arguments;return new Promise(function(n,o){var i=e.apply(t,r);function a(e){b(i,n,o,a,u,"next",e)}function u(e){b(i,n,o,a,u,"throw",e)}a(void 0)})}).call(this)}}],function(e,t){for(var r=0;r<t.length;r++){var n=t[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,n.key,n)}}(r.prototype,t),r}(x(e.Plugin))}(),p}()});
@@ -11,11 +11,11 @@ module.exports = {
11
11
  "antd": "5.24.2",
12
12
  "react": "18.2.0",
13
13
  "react-router-dom": "6.30.1",
14
- "@nocobase/client": "2.1.0-alpha.40",
15
- "@nocobase/flow-engine": "2.1.0-alpha.40",
16
- "@nocobase/server": "2.1.0-alpha.40",
17
- "@nocobase/cache": "2.1.0-alpha.40",
18
- "@nocobase/plugin-auth": "2.1.0-alpha.40",
19
- "@nocobase/utils": "2.1.0-alpha.40",
20
- "@nocobase/database": "2.1.0-alpha.40"
14
+ "@nocobase/client": "2.1.0-alpha.45",
15
+ "@nocobase/flow-engine": "2.1.0-alpha.45",
16
+ "@nocobase/server": "2.1.0-alpha.45",
17
+ "@nocobase/cache": "2.1.0-alpha.45",
18
+ "@nocobase/plugin-auth": "2.1.0-alpha.45",
19
+ "@nocobase/utils": "2.1.0-alpha.45",
20
+ "@nocobase/database": "2.1.0-alpha.45"
21
21
  };
@@ -1 +1 @@
1
- {"name":"light-my-request","version":"6.6.0","description":"Fake HTTP injection library","main":"index.js","type":"commonjs","types":"types/index.d.ts","dependencies":{"cookie":"^1.0.1","process-warning":"^4.0.0","set-cookie-parser":"^2.6.0"},"devDependencies":{"@fastify/ajv-compiler":"^4.0.0","@fastify/pre-commit":"^2.1.0","@types/node":"^22.7.7","c8":"^10.1.2","end-of-stream":"^1.4.4","eslint":"^9.17.0","express":"^4.19.2","form-auto-content":"^3.2.1","form-data":"^4.0.0","formdata-node":"^6.0.3","multer":"^1.4.5-lts.1","neostandard":"^0.12.0","tinybench":"^3.0.0","tsd":"^0.31.0","undici":"^7.0.0"},"scripts":{"benchmark":"node benchmark/benchmark.js","coverage":"npm run unit -- --cov --coverage-report=html","lint":"eslint","lint:fix":"eslint --fix","test":"npm run lint && npm run test:unit && npm run test:typescript","test:typescript":"tsd","test:unit":"c8 --100 node --test"},"repository":{"type":"git","url":"git+https://github.com/fastify/light-my-request.git"},"keywords":["http","inject","fake","request","server"],"author":"Tomas Della Vedova - @delvedor (http://delved.org)","contributors":[{"name":"Matteo Collina","email":"hello@matteocollina.com"},{"name":"Manuel Spigolon","email":"behemoth89@gmail.com"},{"name":"Aras Abbasi","email":"aras.abbasi@gmail.com"},{"name":"Frazer Smith","email":"frazer.dev@icloud.com","url":"https://github.com/fdawgs"}],"license":"BSD-3-Clause","bugs":{"url":"https://github.com/fastify/light-my-request/issues"},"homepage":"https://github.com/fastify/light-my-request#readme","funding":[{"type":"github","url":"https://github.com/sponsors/fastify"},{"type":"opencollective","url":"https://opencollective.com/fastify"}],"_lastModified":"2026-05-21T22:22:19.867Z"}
1
+ {"name":"light-my-request","version":"6.6.0","description":"Fake HTTP injection library","main":"index.js","type":"commonjs","types":"types/index.d.ts","dependencies":{"cookie":"^1.0.1","process-warning":"^4.0.0","set-cookie-parser":"^2.6.0"},"devDependencies":{"@fastify/ajv-compiler":"^4.0.0","@fastify/pre-commit":"^2.1.0","@types/node":"^22.7.7","c8":"^10.1.2","end-of-stream":"^1.4.4","eslint":"^9.17.0","express":"^4.19.2","form-auto-content":"^3.2.1","form-data":"^4.0.0","formdata-node":"^6.0.3","multer":"^1.4.5-lts.1","neostandard":"^0.12.0","tinybench":"^3.0.0","tsd":"^0.31.0","undici":"^7.0.0"},"scripts":{"benchmark":"node benchmark/benchmark.js","coverage":"npm run unit -- --cov --coverage-report=html","lint":"eslint","lint:fix":"eslint --fix","test":"npm run lint && npm run test:unit && npm run test:typescript","test:typescript":"tsd","test:unit":"c8 --100 node --test"},"repository":{"type":"git","url":"git+https://github.com/fastify/light-my-request.git"},"keywords":["http","inject","fake","request","server"],"author":"Tomas Della Vedova - @delvedor (http://delved.org)","contributors":[{"name":"Matteo Collina","email":"hello@matteocollina.com"},{"name":"Manuel Spigolon","email":"behemoth89@gmail.com"},{"name":"Aras Abbasi","email":"aras.abbasi@gmail.com"},{"name":"Frazer Smith","email":"frazer.dev@icloud.com","url":"https://github.com/fdawgs"}],"license":"BSD-3-Clause","bugs":{"url":"https://github.com/fastify/light-my-request/issues"},"homepage":"https://github.com/fastify/light-my-request#readme","funding":[{"type":"github","url":"https://github.com/sponsors/fastify"},{"type":"opencollective","url":"https://opencollective.com/fastify"}],"_lastModified":"2026-05-29T12:50:10.549Z"}
@@ -1 +1 @@
1
- {"name":"ms","version":"2.1.3","description":"Tiny millisecond conversion utility","repository":"vercel/ms","main":"./index","files":["index.js"],"scripts":{"precommit":"lint-staged","lint":"eslint lib/* bin/*","test":"mocha tests.js"},"eslintConfig":{"extends":"eslint:recommended","env":{"node":true,"es6":true}},"lint-staged":{"*.js":["npm run lint","prettier --single-quote --write","git add"]},"license":"MIT","devDependencies":{"eslint":"4.18.2","expect.js":"0.3.1","husky":"0.14.3","lint-staged":"5.0.0","mocha":"4.0.1","prettier":"2.0.5"},"_lastModified":"2026-05-21T22:22:19.917Z"}
1
+ {"name":"ms","version":"2.1.3","description":"Tiny millisecond conversion utility","repository":"vercel/ms","main":"./index","files":["index.js"],"scripts":{"precommit":"lint-staged","lint":"eslint lib/* bin/*","test":"mocha tests.js"},"eslintConfig":{"extends":"eslint:recommended","env":{"node":true,"es6":true}},"lint-staged":{"*.js":["npm run lint","prettier --single-quote --write","git add"]},"license":"MIT","devDependencies":{"eslint":"4.18.2","expect.js":"0.3.1","husky":"0.14.3","lint-staged":"5.0.0","mocha":"4.0.1","prettier":"2.0.5"},"_lastModified":"2026-05-29T12:50:10.661Z"}
@@ -0,0 +1,12 @@
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
+ import Application from '@nocobase/server';
10
+ import type { IdpOauthService } from './service';
11
+ import type { AdapterConstructor } from 'oidc-provider';
12
+ export declare function createOidcAdapter(app: Application, service: IdpOauthService, collectionName?: string): AdapterConstructor;
@@ -0,0 +1,73 @@
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 adapter_exports = {};
28
+ __export(adapter_exports, {
29
+ createOidcAdapter: () => createOidcAdapter
30
+ });
31
+ module.exports = __toCommonJS(adapter_exports);
32
+ var import_db_adapter = require("./db-adapter");
33
+ function createOidcAdapter(app, service, collectionName = "oidcStates") {
34
+ const DbAdapter = (0, import_db_adapter.createDbAdapter)(app, collectionName);
35
+ return class OidcAdapter {
36
+ constructor(model) {
37
+ this.model = model;
38
+ this.dbAdapter = new DbAdapter(model);
39
+ }
40
+ dbAdapter;
41
+ async find(id) {
42
+ if (this.model === "Client") {
43
+ const resolvedClient = await service.resolveClient(id);
44
+ if (resolvedClient) {
45
+ return resolvedClient;
46
+ }
47
+ }
48
+ return this.dbAdapter.find(id);
49
+ }
50
+ async findByUserCode(userCode) {
51
+ return this.dbAdapter.findByUserCode(userCode);
52
+ }
53
+ async findByUid(uid) {
54
+ return this.dbAdapter.findByUid(uid);
55
+ }
56
+ async upsert(id, payload, expiresIn) {
57
+ return this.dbAdapter.upsert(id, payload, expiresIn);
58
+ }
59
+ async consume(id) {
60
+ return this.dbAdapter.consume(id);
61
+ }
62
+ async destroy(id) {
63
+ return this.dbAdapter.destroy(id);
64
+ }
65
+ async revokeByGrantId(grantId) {
66
+ return this.dbAdapter.revokeByGrantId(grantId);
67
+ }
68
+ };
69
+ }
70
+ // Annotate the CommonJS export names for ESM import in node:
71
+ 0 && (module.exports = {
72
+ createOidcAdapter
73
+ });
@@ -44,6 +44,12 @@ function getInteractionPromptDetails(details) {
44
44
  const missingResourceScopes = Object.entries(promptDetails.missingResourceScopes || {}).map(([resource, scopes]) => `${resource}: ${asStringArray(scopes).join(" ")}`).join("; ");
45
45
  return [missingScope, missingClaims, missingResourceScopes].filter(Boolean).join(" | ");
46
46
  }
47
+ function shouldSkipConsent(clientId) {
48
+ return clientId.startsWith("app:");
49
+ }
50
+ function getClientId(details) {
51
+ return String(details.params.client_id || "");
52
+ }
47
53
  async function getInteractionRedirect(ctx, provider, service, result, mergeWithLastSubmission) {
48
54
  const redirectTo = await provider.interactionResult(ctx.req, ctx.res, result, {
49
55
  mergeWithLastSubmission
@@ -63,6 +69,65 @@ async function completeLogin(ctx, provider, service, accountId) {
63
69
  false
64
70
  );
65
71
  }
72
+ async function createConsentGrant(provider, details, accountId) {
73
+ const promptDetails = getPromptDetails(details);
74
+ const clientId = getClientId(details);
75
+ let grant;
76
+ if (details.grantId) {
77
+ grant = await provider.Grant.find(details.grantId);
78
+ } else {
79
+ grant = new provider.Grant({
80
+ accountId,
81
+ clientId
82
+ });
83
+ }
84
+ const missingOIDCScope = asStringArray(promptDetails.missingOIDCScope);
85
+ const requestedScope = typeof details.params.scope === "string" ? details.params.scope.split(/\s+/).filter(Boolean) : [];
86
+ const oidcScope = missingOIDCScope.length ? missingOIDCScope : requestedScope;
87
+ if (oidcScope.length) {
88
+ grant.addOIDCScope(oidcScope.join(" "));
89
+ }
90
+ const missingOIDCClaims = asStringArray(promptDetails.missingOIDCClaims);
91
+ if (missingOIDCClaims.length) {
92
+ grant.addOIDCClaims(missingOIDCClaims);
93
+ }
94
+ const missingResourceScopes = promptDetails.missingResourceScopes || {};
95
+ if (Object.keys(missingResourceScopes).length) {
96
+ for (const [indicator, scopes] of Object.entries(missingResourceScopes)) {
97
+ grant.addResourceScope(indicator, asStringArray(scopes).join(" "));
98
+ }
99
+ }
100
+ return grant.save();
101
+ }
102
+ async function completeTrustedAppLogin(ctx, provider, service, details, accountId) {
103
+ return getInteractionRedirect(
104
+ ctx,
105
+ provider,
106
+ service,
107
+ {
108
+ login: {
109
+ accountId
110
+ },
111
+ consent: {
112
+ grantId: await createConsentGrant(provider, details, accountId)
113
+ }
114
+ },
115
+ false
116
+ );
117
+ }
118
+ async function completeConsent(ctx, provider, service, details, accountId) {
119
+ return getInteractionRedirect(
120
+ ctx,
121
+ provider,
122
+ service,
123
+ {
124
+ consent: {
125
+ grantId: await createConsentGrant(provider, details, accountId)
126
+ }
127
+ },
128
+ true
129
+ );
130
+ }
66
131
  async function handleInteractionGet(ctx, provider, user, service) {
67
132
  var _a;
68
133
  const details = await provider.interactionDetails(ctx.req, ctx.res);
@@ -74,14 +139,21 @@ async function handleInteractionGet(ctx, provider, user, service) {
74
139
  };
75
140
  return;
76
141
  }
142
+ const clientId = getClientId(details);
77
143
  ctx.body = {
78
- redirectTo: await completeLogin(ctx, provider, service, String(interactionUser.id))
144
+ redirectTo: shouldSkipConsent(clientId) ? await completeTrustedAppLogin(ctx, provider, service, details, String(interactionUser.id)) : await completeLogin(ctx, provider, service, String(interactionUser.id))
79
145
  };
80
146
  return;
81
147
  }
82
148
  if (details.prompt.name === "consent") {
83
- const clientId = String(details.params.client_id || "");
149
+ const clientId = getClientId(details);
84
150
  const client = await provider.Client.find(clientId);
151
+ if (interactionUser && shouldSkipConsent(clientId)) {
152
+ ctx.body = {
153
+ redirectTo: await completeConsent(ctx, provider, service, details, String(interactionUser.id))
154
+ };
155
+ return;
156
+ }
85
157
  ctx.body = {
86
158
  prompt: "consent",
87
159
  clientName: (client == null ? void 0 : client.clientName) || (client == null ? void 0 : client.clientId) || clientId,
@@ -123,43 +195,8 @@ async function handleInteractionPost(ctx, provider, user, service) {
123
195
  return;
124
196
  }
125
197
  if (details.prompt.name === "consent") {
126
- const promptDetails = getPromptDetails(details);
127
- const clientId = String(details.params.client_id || "");
128
- let grant;
129
- if (details.grantId) {
130
- grant = await provider.Grant.find(details.grantId);
131
- } else {
132
- grant = new provider.Grant({
133
- accountId: String(interactionUser.id),
134
- clientId
135
- });
136
- }
137
- const missingOIDCScope = asStringArray(promptDetails.missingOIDCScope);
138
- if (missingOIDCScope.length) {
139
- grant.addOIDCScope(missingOIDCScope.join(" "));
140
- }
141
- const missingOIDCClaims = asStringArray(promptDetails.missingOIDCClaims);
142
- if (missingOIDCClaims.length) {
143
- grant.addOIDCClaims(missingOIDCClaims);
144
- }
145
- const missingResourceScopes = promptDetails.missingResourceScopes || {};
146
- if (Object.keys(missingResourceScopes).length) {
147
- for (const [indicator, scopes] of Object.entries(missingResourceScopes)) {
148
- grant.addResourceScope(indicator, asStringArray(scopes).join(" "));
149
- }
150
- }
151
198
  ctx.body = {
152
- redirectTo: await getInteractionRedirect(
153
- ctx,
154
- provider,
155
- service,
156
- {
157
- consent: {
158
- grantId: await grant.save()
159
- }
160
- },
161
- true
162
- )
199
+ redirectTo: await completeConsent(ctx, provider, service, details, String(interactionUser.id))
163
200
  };
164
201
  return;
165
202
  }
@@ -10,6 +10,7 @@ import { Plugin } from '@nocobase/server';
10
10
  import { IdpOauthService } from './service';
11
11
  export declare class PluginIdpOauthServer extends Plugin {
12
12
  service: IdpOauthService;
13
+ constructor(...args: ConstructorParameters<typeof Plugin>);
13
14
  private registerDefaultApiResource;
14
15
  load(): Promise<void>;
15
16
  remove(): Promise<void>;
@@ -38,6 +38,10 @@ var import_service = require("./service");
38
38
  var import_utils = require("./utils");
39
39
  class PluginIdpOauthServer extends import_server.Plugin {
40
40
  service;
41
+ constructor(...args) {
42
+ super(...args);
43
+ this.service = new import_service.IdpOauthService(this.app);
44
+ }
41
45
  registerDefaultApiResource() {
42
46
  this.service.registerResourceServer("api", {
43
47
  path: "/",
@@ -49,12 +53,16 @@ class PluginIdpOauthServer extends import_server.Plugin {
49
53
  });
50
54
  }
51
55
  async load() {
52
- const bridgeTokenCache = await this.app.cacheManager.createCache({
53
- name: "idp-oauth-token",
54
- prefix: "idp-oauth:token",
55
- store: "memory"
56
+ this.app.on("auth:signOut", async ({ ctx }) => {
57
+ var _a, _b;
58
+ try {
59
+ await this.service.destroyProviderSession(ctx);
60
+ } catch (error) {
61
+ (_b = (_a = ctx.logger) == null ? void 0 : _a.warn) == null ? void 0 : _b.call(_a, "failed to destroy idp-oauth provider session", {
62
+ error: error instanceof Error ? error.message : String(error)
63
+ });
64
+ }
56
65
  });
57
- this.service = new import_service.IdpOauthService(this.app, bridgeTokenCache);
58
66
  this.registerDefaultApiResource();
59
67
  const paths = (0, import_paths.createIdpOauthPaths)();
60
68
  this.app.use(
@@ -68,6 +68,15 @@ function assertRegistrationRedirectUris(ctx, pathname) {
68
68
  return true;
69
69
  }
70
70
  const body = getRequestBody(ctx);
71
+ const clientId = body == null ? void 0 : body.client_id;
72
+ if (typeof clientId === "string" && clientId.startsWith("app:")) {
73
+ ctx.status = 400;
74
+ ctx.body = {
75
+ error: "invalid_client_metadata",
76
+ error_description: "client_id prefix app: is reserved"
77
+ };
78
+ return false;
79
+ }
71
80
  const redirectUris = body == null ? void 0 : body.redirect_uris;
72
81
  if (!Array.isArray(redirectUris) || !redirectUris.length || !redirectUris.every((uri) => typeof uri === "string" && isLoopbackRedirectUri(uri))) {
73
82
  ctx.status = 400;
@@ -283,7 +292,10 @@ async function dispatchToProvider(ctx, provider, pathname, service) {
283
292
  }
284
293
  async function dispatchCurrentRequestToProvider(ctx, service, apiBasePath) {
285
294
  const provider = await service.ensureProviderForContext(ctx);
286
- return dispatchToProvider(ctx, provider, (0, import_paths.getProviderInternalPath)(ctx.path, apiBasePath), service);
295
+ return service.runWithProviderContext(
296
+ ctx,
297
+ () => dispatchToProvider(ctx, provider, (0, import_paths.getProviderInternalPath)(ctx.path, apiBasePath), service)
298
+ );
287
299
  }
288
300
  // Annotate the CommonJS export names for ESM import in node:
289
301
  0 && (module.exports = {
@@ -19,20 +19,27 @@ export type ResourceServerConfig = {
19
19
  accessTokenFormat?: TokenFormat;
20
20
  jwt?: ResourceServer['jwt'];
21
21
  };
22
- type ProviderContext = {
22
+ export type ProviderContext = {
23
23
  appName: string;
24
24
  issuer: string;
25
25
  issuerPath: string;
26
26
  origin: string;
27
27
  };
28
+ export type OidcClientMetadata = import('oidc-provider').ClientMetadata;
29
+ export type OidcClientResolver = {
30
+ resolveClient(clientId: string, providerContext?: ProviderContext): Promise<OidcClientMetadata | null | undefined> | OidcClientMetadata | null | undefined;
31
+ };
28
32
  export declare class IdpOauthService {
29
33
  private readonly app;
30
- private readonly bridgeTokenCache;
34
+ private bridgeTokenCache?;
31
35
  private providers;
32
36
  private pendingProviders;
33
37
  private resourceServers;
34
38
  private resourceJwks;
35
- constructor(app: Application, bridgeTokenCache: Cache);
39
+ private clientResolvers;
40
+ private providerContextStorage;
41
+ constructor(app: Application, bridgeTokenCache?: Cache);
42
+ private getBridgeTokenCache;
36
43
  getOrigin(ctx: any): string;
37
44
  private getApiBasePath;
38
45
  private getRequestPath;
@@ -43,8 +50,13 @@ export declare class IdpOauthService {
43
50
  getFrontendInteractionPath(appName: string, uid: string, issuerPath?: string): string;
44
51
  getFrontendErrorPath(appName: string, issuerPath?: string): string;
45
52
  getProviderContext(ctx: any): ProviderContext;
53
+ getCurrentProviderContext(): ProviderContext;
54
+ runWithProviderContext<T>(ctx: any, callback: () => T): T;
46
55
  registerResourceServer(name: string, config: ResourceServerConfig): void;
47
56
  unregisterResourceServer(name: string): void;
57
+ registerClientResolver(name: string, resolver: OidcClientResolver): void;
58
+ unregisterClientResolver(name: string): void;
59
+ resolveClient(clientId: string): Promise<import("oidc-provider").ClientMetadata>;
48
60
  getSupportedScopes(): string[];
49
61
  private resolveResourceIdentifier;
50
62
  private getResourceServerInfo;
@@ -59,6 +71,7 @@ export declare class IdpOauthService {
59
71
  private getBridgeTokenCacheKey;
60
72
  private findUserById;
61
73
  resolveInteractionSessionUser(accountId?: string | number): Promise<any>;
74
+ destroyProviderSession(ctx: any): Promise<void>;
62
75
  resolveInteractionBridgeUser(ctx: any): Promise<any>;
63
76
  authenticateResourceRequest(ctx: any): Promise<any>;
64
77
  private getPublicErrorLocation;
@@ -43,11 +43,12 @@ var import_plugin_auth = require("@nocobase/plugin-auth");
43
43
  var import_server = require("@nocobase/server");
44
44
  var import_node_fs = __toESM(require("node:fs"));
45
45
  var import_light_my_request = __toESM(require("light-my-request"));
46
+ var import_node_async_hooks = require("node:async_hooks");
46
47
  var import_node_crypto = require("node:crypto");
47
48
  var import_node_path = __toESM(require("node:path"));
48
49
  var import_utils = require("@nocobase/utils");
49
50
  var import_ms = __toESM(require("ms"));
50
- var import_db_adapter = require("./db-adapter");
51
+ var import_adapter = require("./adapter");
51
52
  var import_utils2 = require("./utils");
52
53
  let oidcModulePromise = null;
53
54
  let joseModulePromise = null;
@@ -66,8 +67,8 @@ function getJoseModule() {
66
67
  const defaultSupportedScopes = ["openid", "offline_access", "profile", "email"];
67
68
  const envJwksKeys = ["IDP_OAUTH_JWKS", "OAUTH_JWKS"];
68
69
  const MAX_CACHE_TTL_MS = 2147483647;
69
- const DEFAULT_ACCESS_TOKEN_TTL_SECONDS = Math.floor((0, import_ms.default)(import_plugin_auth.defaultTokenPolicyConfig.tokenExpirationTime) / 1e3);
70
- const DEFAULT_SESSION_TTL_SECONDS = Math.floor((0, import_ms.default)(import_plugin_auth.defaultTokenPolicyConfig.sessionExpirationTime) / 1e3);
70
+ const DEFAULT_ACCESS_TOKEN_TTL_SECONDS = Math.floor((0, import_ms.default)(String(import_plugin_auth.defaultTokenPolicyConfig.tokenExpirationTime)) / 1e3);
71
+ const DEFAULT_SESSION_TTL_SECONDS = Math.floor((0, import_ms.default)(String(import_plugin_auth.defaultTokenPolicyConfig.sessionExpirationTime)) / 1e3);
71
72
  function policyMillisecondsToSeconds(value, fallback) {
72
73
  if (typeof value !== "number" || !Number.isFinite(value) || value <= 0) {
73
74
  return fallback;
@@ -83,6 +84,18 @@ class IdpOauthService {
83
84
  pendingProviders = /* @__PURE__ */ new Map();
84
85
  resourceServers = /* @__PURE__ */ new Map();
85
86
  resourceJwks = /* @__PURE__ */ new Map();
87
+ clientResolvers = /* @__PURE__ */ new Map();
88
+ providerContextStorage = new import_node_async_hooks.AsyncLocalStorage();
89
+ async getBridgeTokenCache() {
90
+ if (!this.bridgeTokenCache) {
91
+ this.bridgeTokenCache = await this.app.cacheManager.createCache({
92
+ name: "idp-oauth-token",
93
+ prefix: "idp-oauth:token",
94
+ store: "memory"
95
+ });
96
+ }
97
+ return this.bridgeTokenCache;
98
+ }
86
99
  getOrigin(ctx) {
87
100
  var _a, _b;
88
101
  const protocol = ((_a = ctx.headers) == null ? void 0 : _a["x-forwarded-proto"]) || ctx.protocol || "http";
@@ -165,12 +178,34 @@ class IdpOauthService {
165
178
  origin
166
179
  };
167
180
  }
181
+ getCurrentProviderContext() {
182
+ return this.providerContextStorage.getStore();
183
+ }
184
+ runWithProviderContext(ctx, callback) {
185
+ return this.providerContextStorage.run(this.getProviderContext(ctx), callback);
186
+ }
168
187
  registerResourceServer(name, config) {
169
188
  this.resourceServers.set(name, config);
170
189
  }
171
190
  unregisterResourceServer(name) {
172
191
  this.resourceServers.delete(name);
173
192
  }
193
+ registerClientResolver(name, resolver) {
194
+ this.clientResolvers.set(name, resolver);
195
+ }
196
+ unregisterClientResolver(name) {
197
+ this.clientResolvers.delete(name);
198
+ }
199
+ async resolveClient(clientId) {
200
+ const providerContext = this.getCurrentProviderContext();
201
+ for (const resolver of this.clientResolvers.values()) {
202
+ const client = await resolver.resolveClient(clientId, providerContext);
203
+ if (client) {
204
+ return client;
205
+ }
206
+ }
207
+ return void 0;
208
+ }
174
209
  getSupportedScopes() {
175
210
  const supportedScopes = new Set(defaultSupportedScopes);
176
211
  for (const config of this.resourceServers.values()) {
@@ -343,6 +378,19 @@ class IdpOauthService {
343
378
  }
344
379
  return this.findUserById(accountId);
345
380
  }
381
+ async destroyProviderSession(ctx) {
382
+ var _a, _b, _c;
383
+ const provider = await this.ensureProviderForContext(ctx);
384
+ const session = await provider.Session.get(ctx);
385
+ if (session && !session.new) {
386
+ await session.destroy();
387
+ }
388
+ (_c = (_a = ctx.cookies) == null ? void 0 : _a.set) == null ? void 0 : _c.call(_a, provider.cookieName("session"), null, {
389
+ httpOnly: true,
390
+ sameSite: "lax",
391
+ secure: (((_b = ctx.headers) == null ? void 0 : _b["x-forwarded-proto"]) || ctx.protocol) === "https"
392
+ });
393
+ }
346
394
  async resolveInteractionBridgeUser(ctx) {
347
395
  var _a, _b, _c, _d, _e, _f;
348
396
  const token = (_a = ctx.getBearerToken) == null ? void 0 : _a.call(ctx);
@@ -464,10 +512,11 @@ class IdpOauthService {
464
512
  token,
465
513
  typeof payload.jti === "string" ? payload.jti : void 0
466
514
  );
467
- const cachedInternalToken = await this.bridgeTokenCache.get(bridgeTokenCacheKey);
515
+ const bridgeTokenCache = await this.getBridgeTokenCache();
516
+ const cachedInternalToken = await bridgeTokenCache.get(bridgeTokenCacheKey);
468
517
  const internalToken = cachedInternalToken || await this.issueInternalToken(user.id, oauthExpiresInMs);
469
518
  if (!cachedInternalToken && typeof oauthExpiresInMs === "number" && oauthExpiresInMs > 0) {
470
- await this.bridgeTokenCache.set(bridgeTokenCacheKey, internalToken, Math.min(oauthExpiresInMs, MAX_CACHE_TTL_MS));
519
+ await bridgeTokenCache.set(bridgeTokenCacheKey, internalToken, Math.min(oauthExpiresInMs, MAX_CACHE_TTL_MS));
471
520
  }
472
521
  const authorizationHeader = `Bearer ${internalToken}`;
473
522
  ctx.req.headers.authorization = authorizationHeader;
@@ -505,7 +554,7 @@ class IdpOauthService {
505
554
  );
506
555
  const sessionTtl = policyMillisecondsToSeconds(tokenPolicy == null ? void 0 : tokenPolicy.sessionExpirationTime, DEFAULT_SESSION_TTL_SECONDS);
507
556
  return {
508
- adapter: (0, import_db_adapter.createDbAdapter)(this.app, "oidcStates"),
557
+ adapter: (0, import_adapter.createOidcAdapter)(this.app, this, "oidcStates"),
509
558
  clients: [],
510
559
  scopes: this.getSupportedScopes(),
511
560
  jwks,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nocobase/plugin-idp-oauth",
3
- "version": "2.1.0-alpha.40",
3
+ "version": "2.1.0-alpha.45",
4
4
  "main": "dist/server/index.js",
5
5
  "displayName": "IdP: OAuth",
6
6
  "displayName.zh-CN": "IdP: OAuth",
@@ -22,5 +22,5 @@
22
22
  "keywords": [
23
23
  "Authentication"
24
24
  ],
25
- "gitHead": "e73f99dd0abefe847f2e50ff0fea1f41a82fd048"
25
+ "gitHead": "e9e24987e12d0ad10a5db8815b1e1b7b447f1938"
26
26
  }