From 5e914ccd6d6320072f8dfe2ea9eb99a9dc8fae4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=91=A8=E9=9B=85=E9=A3=8E?= Date: Thu, 18 Apr 2024 13:53:37 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E4=BC=98=E5=8C=96=20register=20api?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 1 - src/__tests__/index.test.ts | 21 +++++-- src/index.ts | 37 +++++++++++- src/lib/AuthzUrlBuilder.ts | 112 +++++++++++++++++++----------------- yarn.lock | 4 -- 5 files changed, 110 insertions(+), 65 deletions(-) diff --git a/package.json b/package.json index 4710af7..78636ac 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,6 @@ }, "dependencies": { "@babel/runtime": "^7.16.3", - "add": "^2.0.6", "axios": "^0.24.0", "core-js": "3", "url-polyfill": "^1.1.12", diff --git a/src/__tests__/index.test.ts b/src/__tests__/index.test.ts index de4ca0c..6c775d1 100644 --- a/src/__tests__/index.test.ts +++ b/src/__tests__/index.test.ts @@ -40,10 +40,23 @@ describe('Test AuthingSSO', () => { test('Init AuthingSSO', () => { expect(auth).toBeInstanceOf(AuthingSSO) }) - + // 非 Electron - test('register function to be called', () => { - auth.register() + test('register function to be called', () => { + const stateStr = Math.random().toString() + const nonceStr = Math.random().toString() + const scopeStr = 'openid phone' + const responseModeStr = 'fragment' + const responseTypeStr = 'token id_token' + const promptStr = 'login' + auth.register({ + scope: scopeStr, + responseMode: responseModeStr, + responseType: responseTypeStr, + state: stateStr, + nonce: nonceStr, + prompt: promptStr + }) expect(window.open).not.toBeCalled() }) @@ -110,7 +123,7 @@ describe('Test AuthingSSO', () => { .state(stateStr) .nonce(nonceStr) .build() - + const iframe = document.createElement('iframe') iframe.title = 'postMessage() Initiator' iframe.src = url.href diff --git a/src/index.ts b/src/index.ts index 43c2c0c..7d7e6cf 100644 --- a/src/index.ts +++ b/src/index.ts @@ -82,8 +82,39 @@ export class AuthingSSO { * @msg: 注册方法 * @param {*} */ - register() { - let url = new URL(this.origin + '/register') + register(options: ILoginParams) { + // let url = new URL(this.origin + '/register') + const registerContext = { + goto:"/register" + } + + + + const { + scope, + responseMode, + responseType, + prompt, + state, + nonce + } = Object.assign({}, { + scope: 'openid profile email phone', + responseMode: 'fragment', + responseType: 'id_token token' + }, options) + + let url = this.authzUrlBuilder + .redirectUri(this.redirectUri) + .scope(scope) + .responseMode(responseMode) + .responseType(responseType) + .clientId(this.appId) + .prompt(prompt) + .state(state) + .nonce(nonce) + .loginPageContext(JSON.stringify(registerContext)) + .build() + if (isInElectron) { window.open(url.href) } else { @@ -108,7 +139,7 @@ export class AuthingSSO { responseMode: 'fragment', responseType: 'id_token token' }, options) - + let url = this.authzUrlBuilder .redirectUri(this.redirectUri) .scope(scope) diff --git a/src/lib/AuthzUrlBuilder.ts b/src/lib/AuthzUrlBuilder.ts index 4119711..45da598 100644 --- a/src/lib/AuthzUrlBuilder.ts +++ b/src/lib/AuthzUrlBuilder.ts @@ -1,112 +1,118 @@ - -import { InvalidParamsError } from '../errors/InvalidParamsError' -import { IPromptType } from '../interfaces/IAuthingSSOConstructorParams' +import { InvalidParamsError } from "../errors/InvalidParamsError"; +import { IPromptType } from "../interfaces/IAuthingSSOConstructorParams"; export class AuthzUrlBuilder { - - private _clientId: string - private _origin: string - private _redirectUri: string - private _responseType: string = 'code' - private _responseMode: string = 'fragment' - private _prompt: string | undefined - private _state: string = Math.random().toString() - private _nonce: string - private _scope: string = 'openid email phone profile offline_access' + private _clientId: string; + private _origin: string; + private _redirectUri: string; + private _responseType: string = "code"; + private _responseMode: string = "fragment"; + private _prompt: string | undefined; + private _state: string = Math.random().toString(); + private _nonce: string; + private _scope: string = "openid email phone profile offline_access"; + private _loginPageContext: string; constructor(origin: string, appid: string, redirectUri: string) { if (!origin) { - throw new InvalidParamsError('URL 构造器必须传入 origin,值为通信 URL 的域,例如:https://userpool1.authing.cn') + throw new InvalidParamsError( + "URL 构造器必须传入 origin,值为通信 URL 的域,例如:https://userpool1.authing.cn" + ); } if (!appid) { - throw new InvalidParamsError('URL 构造器必须传入 clientid') + throw new InvalidParamsError("URL 构造器必须传入 clientid"); } if (!redirectUri) { - throw new InvalidParamsError('URL 构造器必须传入 redirectUri') + throw new InvalidParamsError("URL 构造器必须传入 redirectUri"); } - this._origin = origin - this._redirectUri = redirectUri - this._clientId = appid + this._origin = origin; + this._redirectUri = redirectUri; + this._clientId = appid; } build() { - let urls = new URL(this._origin) + let urls = new URL(this._origin); - urls.pathname = '/oidc/auth' + urls.pathname = "/oidc/auth"; - urls.searchParams.append('redirect_uri', this._redirectUri) - urls.searchParams.append('scope', this._scope) - urls.searchParams.append('response_mode', this._responseMode) - urls.searchParams.append('response_type', this._responseType) - urls.searchParams.append('client_id', this._clientId) + urls.searchParams.append("redirect_uri", this._redirectUri); + urls.searchParams.append("scope", this._scope); + urls.searchParams.append("response_mode", this._responseMode); + urls.searchParams.append("response_type", this._responseType); + urls.searchParams.append("client_id", this._clientId); + urls.searchParams.append("login_page_context", this._loginPageContext); if (this._prompt) { - urls.searchParams.append('prompt', this._prompt) + urls.searchParams.append("prompt", this._prompt); } if (this._state) { - urls.searchParams.append('state', this._state) + urls.searchParams.append("state", this._state); } if (this._nonce) { - urls.searchParams.append('nonce', this._nonce) + urls.searchParams.append("nonce", this._nonce); } - return urls + return urls; } redirectUri(url: string) { - this._redirectUri = encodeURI(url) - return this + this._redirectUri = encodeURI(url); + return this; } scope(params: string) { - const openidRequiredMessage = 'AuthingSSO error: scope 必须传递 openid' + const openidRequiredMessage = "AuthingSSO error: scope 必须传递 openid"; if (!params) { - throw new InvalidParamsError(openidRequiredMessage) + throw new InvalidParamsError(openidRequiredMessage); } - const _params: string[] = params.split(' ').filter(item => !!item) + const _params: string[] = params.split(" ").filter((item) => !!item); - if (_params.includes('offline_access')) { - this._prompt = 'consent' + if (_params.includes("offline_access")) { + this._prompt = "consent"; } - if (_params.includes('openid')) { - this._scope = _params.join(' ') - return this + if (_params.includes("openid")) { + this._scope = _params.join(" "); + return this; } - throw new InvalidParamsError(openidRequiredMessage) + throw new InvalidParamsError(openidRequiredMessage); } responseMode(params: string) { - this._responseMode = params - return this + this._responseMode = params; + return this; } responseType(params: string) { - this._responseType = params - return this + this._responseType = params; + return this; } clientId(appId: string) { - this._clientId = appId - return this + this._clientId = appId; + return this; } prompt(params: IPromptType) { - this._prompt = params - return this + this._prompt = params; + return this; } state(timestamp: string) { - this._state = timestamp - return this + this._state = timestamp; + return this; } nonce(rand: string) { - this._nonce = rand - return this + this._nonce = rand; + return this; + } + loginPageContext(context: string) { + this._loginPageContext = context; + return this; } } diff --git a/yarn.lock b/yarn.lock index 090cc47..d3574d3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1697,10 +1697,6 @@ add-stream@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/add-stream/-/add-stream-1.0.0.tgz" -add@^2.0.6: - version "2.0.6" - resolved "https://registry.npm.taobao.org/add/download/add-2.0.6.tgz" - address@>=0.0.1, address@^1.0.0: version "1.1.2" resolved "https://registry.npmjs.org/address/-/address-1.1.2.tgz"