@pubinfo/module-auth 2.0.0-beta.32 → 2.0.0-rc.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/dist/index.d.ts +26 -30
- package/dist/index.js +104 -74
- package/dist/{interface-CSPrYibH.d.ts → interface-CqwWb8Fb.d.ts} +6 -3
- package/dist/providers/4A.d.ts +1 -1
- package/dist/providers/credentials.d.ts +1 -1
- package/dist/providers/ding-zj.d.ts +1 -1
- package/package.json +3 -3
- package/src/context.ts +20 -0
- package/src/core.ts +83 -91
- package/src/index.ts +10 -6
- package/src/interface.ts +7 -2
package/dist/index.d.ts
CHANGED
|
@@ -1,38 +1,34 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { AuthOptions, Authorization, Fn, FnApi, InternalContext, ProviderConfig, ProviderUserConfig, Recordable, ThirdParty } from "./interface-CqwWb8Fb.js";
|
|
2
2
|
import { ModuleOptions } from "pubinfo";
|
|
3
3
|
|
|
4
4
|
//#region src/core.d.ts
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* 前往登录
|
|
8
|
+
* @param id 唯一值
|
|
9
|
+
* @param options 登录时需要传递的参数
|
|
10
|
+
*/
|
|
11
|
+
declare function signIn(id: ThirdParty, options?: Recordable): Promise<any>;
|
|
12
|
+
/**
|
|
13
|
+
* 生成二维码
|
|
14
|
+
* @param id 第三方的唯一值
|
|
15
|
+
* @param options 生成二维码需要传递的参数
|
|
16
|
+
* @param options.id `getElementById`中指定的`id`
|
|
17
|
+
*/
|
|
18
|
+
declare function renderQRCode(id: ThirdParty, options: {
|
|
19
|
+
id: string;
|
|
20
|
+
} & Recordable): void;
|
|
21
|
+
/**
|
|
22
|
+
* 认证
|
|
23
|
+
* @param id 第三方的唯一值
|
|
24
|
+
*/
|
|
25
|
+
declare function authentication(id: ThirdParty): Promise<any>;
|
|
5
26
|
/**
|
|
6
|
-
*
|
|
27
|
+
* 重定向至统一登录页
|
|
7
28
|
*/
|
|
8
|
-
declare function
|
|
9
|
-
/**
|
|
10
|
-
* 前往登录
|
|
11
|
-
* @param id 唯一值
|
|
12
|
-
* @param options 登录时需要传递的参数
|
|
13
|
-
*/
|
|
14
|
-
signIn(id: ThirdParty, options?: Recordable): Promise<any>;
|
|
15
|
-
/**
|
|
16
|
-
* 生成二维码
|
|
17
|
-
* @param id 第三方的唯一值
|
|
18
|
-
* @param options 生成二维码需要传递的参数
|
|
19
|
-
* @param options.id `getElementById`中指定的`id`
|
|
20
|
-
*/
|
|
21
|
-
renderQRCode(id: ThirdParty, options: {
|
|
22
|
-
id: string;
|
|
23
|
-
} & Recordable): void;
|
|
24
|
-
/**
|
|
25
|
-
* 认证
|
|
26
|
-
* @param id 第三方的唯一值
|
|
27
|
-
*/
|
|
28
|
-
authentication(id: ThirdParty): Promise<any>;
|
|
29
|
-
/**
|
|
30
|
-
* 重定向至统一登录页
|
|
31
|
-
*/
|
|
32
|
-
redirect(): void;
|
|
33
|
-
};
|
|
29
|
+
declare function redirect(): void;
|
|
34
30
|
//#endregion
|
|
35
31
|
//#region src/index.d.ts
|
|
36
|
-
declare function
|
|
32
|
+
declare function auth(options: AuthOptions): ModuleOptions;
|
|
37
33
|
//#endregion
|
|
38
|
-
export {
|
|
34
|
+
export { AuthOptions, Authorization, Fn, FnApi, InternalContext, ProviderConfig, ProviderUserConfig, Recordable, ThirdParty, auth, authentication, redirect, renderQRCode, signIn };
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,94 @@
|
|
|
1
|
-
import { cleanup, useUserStore } from "pubinfo";
|
|
1
|
+
import { cleanup, createContext, useUserStore } from "pubinfo";
|
|
2
2
|
import { defineComponent, h, onMounted, ref } from "vue";
|
|
3
3
|
|
|
4
|
+
//#region src/context.ts
|
|
5
|
+
const g = globalThis;
|
|
6
|
+
g.__PUBINFO__ = g.__PUBINFO__ || {};
|
|
7
|
+
if (!g.__PUBINFO__.authCtx) g.__PUBINFO__.authCtx = createContext();
|
|
8
|
+
const ctx = g.__PUBINFO__.authCtx;
|
|
9
|
+
if (g.__PUBINFO__.authState) try {
|
|
10
|
+
ctx.set(g.__PUBINFO__.authState);
|
|
11
|
+
} catch {}
|
|
12
|
+
|
|
13
|
+
//#endregion
|
|
14
|
+
//#region src/core.ts
|
|
15
|
+
/**
|
|
16
|
+
* 获取指定的 `Provider`
|
|
17
|
+
* @param id
|
|
18
|
+
*/
|
|
19
|
+
function getProvider(id) {
|
|
20
|
+
const { providers } = ctx.use();
|
|
21
|
+
const provider = id ? providers?.find((provider$1) => provider$1.id === id) : providers?.[0];
|
|
22
|
+
if (!provider) throw new Error(`Provider '${id}' is not found.`);
|
|
23
|
+
return provider;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* 构建第三方授权登录地址
|
|
27
|
+
* @param provider
|
|
28
|
+
*/
|
|
29
|
+
function createUrl(provider) {
|
|
30
|
+
const { authorization } = provider;
|
|
31
|
+
if (typeof authorization === "function") return "";
|
|
32
|
+
const url = new URL(authorization?.url ?? "");
|
|
33
|
+
const params = new URLSearchParams(authorization?.params ?? {});
|
|
34
|
+
return `${url.toString()}?${params.toString()}`;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* 前往登录
|
|
38
|
+
* @param id 唯一值
|
|
39
|
+
* @param options 登录时需要传递的参数
|
|
40
|
+
*/
|
|
41
|
+
async function signIn(id, options) {
|
|
42
|
+
const provider = getProvider(id);
|
|
43
|
+
const { type, authorization } = provider;
|
|
44
|
+
if (typeof authorization === "function") return await authorization(options);
|
|
45
|
+
if (type === "oauth" || type === "custom") {
|
|
46
|
+
const url = createUrl(provider);
|
|
47
|
+
window.location.replace(url);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* 生成二维码
|
|
52
|
+
* @param id 第三方的唯一值
|
|
53
|
+
* @param options 生成二维码需要传递的参数
|
|
54
|
+
* @param options.id `getElementById`中指定的`id`
|
|
55
|
+
*/
|
|
56
|
+
function renderQRCode(id, options) {
|
|
57
|
+
const provider = getProvider(id);
|
|
58
|
+
const { type, initQRCode } = provider;
|
|
59
|
+
if (type === "oauth" || type === "custom") {
|
|
60
|
+
const url = createUrl(provider);
|
|
61
|
+
initQRCode?.(url, options);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* 认证
|
|
66
|
+
* @param id 第三方的唯一值
|
|
67
|
+
*/
|
|
68
|
+
async function authentication(id) {
|
|
69
|
+
const provider = getProvider(id);
|
|
70
|
+
const { baseURL } = ctx.use();
|
|
71
|
+
const { type, callbackUrl } = provider;
|
|
72
|
+
const qs = window.location.href.split("?")?.[1] ?? "";
|
|
73
|
+
const params = new URLSearchParams(qs);
|
|
74
|
+
if (typeof callbackUrl === "function") return await callbackUrl(Object.fromEntries(params.entries()), baseURL);
|
|
75
|
+
if (type === "oauth" || type === "cas" || type === "custom") {
|
|
76
|
+
const response = await fetch(`${baseURL}${callbackUrl}?${params.toString()}`);
|
|
77
|
+
return await response.json();
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* 重定向至统一登录页
|
|
82
|
+
*/
|
|
83
|
+
function redirect() {
|
|
84
|
+
const { providers } = ctx.use();
|
|
85
|
+
const provider = providers?.find((provider$1) => provider$1.type === "cas");
|
|
86
|
+
if (!provider) return;
|
|
87
|
+
const url = createUrl(provider);
|
|
88
|
+
window.location.replace(url);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
//#endregion
|
|
4
92
|
//#region src/pages/auth.ts
|
|
5
93
|
const PageAuth = defineComponent({
|
|
6
94
|
props: {
|
|
@@ -30,82 +118,24 @@ const PageAuth = defineComponent({
|
|
|
30
118
|
}
|
|
31
119
|
});
|
|
32
120
|
|
|
33
|
-
//#endregion
|
|
34
|
-
//#region src/core.ts
|
|
35
|
-
/**
|
|
36
|
-
* 初始化
|
|
37
|
-
*/
|
|
38
|
-
function createAuth(config = {}) {
|
|
39
|
-
const { baseURL = "", providers = [] } = config;
|
|
40
|
-
/**
|
|
41
|
-
* 获取指定的 `Provider`
|
|
42
|
-
* @param id
|
|
43
|
-
*/
|
|
44
|
-
function getProvider(id) {
|
|
45
|
-
const provider = id ? providers.find((provider$1) => provider$1.id === id) : providers[0];
|
|
46
|
-
if (!provider) throw new Error(`Provider '${id}' is not found.`);
|
|
47
|
-
return provider;
|
|
48
|
-
}
|
|
49
|
-
return {
|
|
50
|
-
async signIn(id, options) {
|
|
51
|
-
const provider = getProvider(id);
|
|
52
|
-
const { type, authorization } = provider;
|
|
53
|
-
if (typeof authorization === "function") return await authorization(options);
|
|
54
|
-
if (type === "oauth" || type === "custom") {
|
|
55
|
-
const url = createUrl(provider);
|
|
56
|
-
window.location.replace(url);
|
|
57
|
-
}
|
|
58
|
-
},
|
|
59
|
-
renderQRCode(id, options) {
|
|
60
|
-
const provider = getProvider(id);
|
|
61
|
-
const { type, initQRCode } = provider;
|
|
62
|
-
if (type === "oauth" || type === "custom") {
|
|
63
|
-
const url = createUrl(provider);
|
|
64
|
-
initQRCode?.(url, options);
|
|
65
|
-
}
|
|
66
|
-
},
|
|
67
|
-
async authentication(id) {
|
|
68
|
-
const provider = getProvider(id);
|
|
69
|
-
const { type, callbackUrl } = provider;
|
|
70
|
-
const qs = window.location.href.split("?")?.[1] ?? "";
|
|
71
|
-
const params = new URLSearchParams(qs);
|
|
72
|
-
if (typeof callbackUrl === "function") return await callbackUrl(Object.fromEntries(params.entries()), baseURL);
|
|
73
|
-
if (type === "oauth" || type === "cas" || type === "custom") {
|
|
74
|
-
const response = await fetch(`${baseURL}${callbackUrl}?${params.toString()}`);
|
|
75
|
-
return await response.json();
|
|
76
|
-
}
|
|
77
|
-
},
|
|
78
|
-
redirect() {
|
|
79
|
-
const provider = providers.find((provider$1) => provider$1.type === "cas");
|
|
80
|
-
if (!provider) return;
|
|
81
|
-
const url = createUrl(provider);
|
|
82
|
-
window.location.replace(url);
|
|
83
|
-
}
|
|
84
|
-
};
|
|
85
|
-
}
|
|
86
|
-
/**
|
|
87
|
-
* 构建第三方授权登录地址
|
|
88
|
-
* @param provider
|
|
89
|
-
*/
|
|
90
|
-
function createUrl(provider) {
|
|
91
|
-
const { authorization } = provider;
|
|
92
|
-
if (typeof authorization === "function") return "";
|
|
93
|
-
const url = new URL(authorization?.url ?? "");
|
|
94
|
-
const params = new URLSearchParams(authorization?.params ?? {});
|
|
95
|
-
return `${url.toString()}?${params.toString()}`;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
121
|
//#endregion
|
|
99
122
|
//#region src/index.ts
|
|
100
|
-
function
|
|
101
|
-
const {
|
|
102
|
-
const {
|
|
103
|
-
|
|
123
|
+
function auth(options) {
|
|
124
|
+
const { redirectTo = "/", pages = {}, baseURL, providers } = options;
|
|
125
|
+
const { signIn: signIn$1 = "/login" } = pages;
|
|
126
|
+
ctx.set({
|
|
127
|
+
baseURL,
|
|
128
|
+
providers
|
|
129
|
+
});
|
|
130
|
+
globalThis.__PUBINFO__.authState = {
|
|
131
|
+
baseURL,
|
|
132
|
+
providers
|
|
133
|
+
};
|
|
104
134
|
return {
|
|
105
135
|
name: "pubinfo:auth",
|
|
106
136
|
enforce: "pre",
|
|
107
|
-
setup(ctx) {
|
|
108
|
-
const { router } = ctx;
|
|
137
|
+
setup(ctx$1) {
|
|
138
|
+
const { router } = ctx$1;
|
|
109
139
|
const ROUTE_AUTH = {
|
|
110
140
|
path: "/auth/:type",
|
|
111
141
|
name: "Auth",
|
|
@@ -128,11 +158,11 @@ function withModule(auth, options = {}) {
|
|
|
128
158
|
return to.fullPath;
|
|
129
159
|
}
|
|
130
160
|
if (to.name === ROUTE_AUTH.name) cleanup();
|
|
131
|
-
if (to.path === signIn) redirect();
|
|
161
|
+
if (to.path === signIn$1) redirect();
|
|
132
162
|
});
|
|
133
163
|
}
|
|
134
164
|
};
|
|
135
165
|
}
|
|
136
166
|
|
|
137
167
|
//#endregion
|
|
138
|
-
export {
|
|
168
|
+
export { auth, authentication, redirect, renderQRCode, signIn };
|
|
@@ -12,10 +12,13 @@ interface AuthOptions {
|
|
|
12
12
|
/** 默认登录页 */
|
|
13
13
|
signIn?: RouteLocationRaw;
|
|
14
14
|
};
|
|
15
|
+
/** 接口的baseURL */
|
|
16
|
+
baseURL: string;
|
|
17
|
+
providers?: ProviderConfig[];
|
|
15
18
|
}
|
|
16
|
-
interface
|
|
19
|
+
interface InternalContext {
|
|
17
20
|
/** 接口的baseURL */
|
|
18
|
-
baseURL
|
|
21
|
+
baseURL: string;
|
|
19
22
|
providers?: ProviderConfig[];
|
|
20
23
|
}
|
|
21
24
|
/** 第三方类型 */
|
|
@@ -53,4 +56,4 @@ interface Authorization {
|
|
|
53
56
|
params?: Recordable;
|
|
54
57
|
}
|
|
55
58
|
//#endregion
|
|
56
|
-
export {
|
|
59
|
+
export { AuthOptions, Authorization, Fn, FnApi, InternalContext, ProviderConfig, ProviderUserConfig, Recordable, ThirdParty };
|
package/dist/providers/4A.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pubinfo/module-auth",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "2.0.0-
|
|
4
|
+
"version": "2.0.0-rc.1",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": {
|
|
7
7
|
"types": "./dist/index.d.ts",
|
|
@@ -20,10 +20,10 @@
|
|
|
20
20
|
"src"
|
|
21
21
|
],
|
|
22
22
|
"peerDependencies": {
|
|
23
|
-
"pubinfo": "2.0.0-
|
|
23
|
+
"pubinfo": "2.0.0-rc.1"
|
|
24
24
|
},
|
|
25
25
|
"devDependencies": {
|
|
26
|
-
"pubinfo": "2.0.0-
|
|
26
|
+
"pubinfo": "2.0.0-rc.1"
|
|
27
27
|
},
|
|
28
28
|
"scripts": {
|
|
29
29
|
"dev": "tsdown --watch src",
|
package/src/context.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { InternalContext } from './interface';
|
|
2
|
+
import { createContext } from 'pubinfo';
|
|
3
|
+
|
|
4
|
+
// 持久化 auth 模块上下文,避免 HMR 后丢失 baseURL/providers
|
|
5
|
+
const g = globalThis as any;
|
|
6
|
+
g.__PUBINFO__ = g.__PUBINFO__ || {};
|
|
7
|
+
if (!g.__PUBINFO__.authCtx) {
|
|
8
|
+
g.__PUBINFO__.authCtx = createContext<InternalContext>();
|
|
9
|
+
}
|
|
10
|
+
export const ctx = g.__PUBINFO__.authCtx as ReturnType<typeof createContext<InternalContext>>;
|
|
11
|
+
|
|
12
|
+
// HMR 恢复
|
|
13
|
+
if (g.__PUBINFO__.authState) {
|
|
14
|
+
try {
|
|
15
|
+
ctx.set(g.__PUBINFO__.authState);
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
// ignore
|
|
19
|
+
}
|
|
20
|
+
}
|
package/src/core.ts
CHANGED
|
@@ -1,98 +1,17 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ProviderUserConfig, Recordable, ThirdParty } from './interface';
|
|
2
|
+
import { ctx } from './context';
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
|
-
*
|
|
5
|
+
* 获取指定的 `Provider`
|
|
6
|
+
* @param id
|
|
5
7
|
*/
|
|
6
|
-
|
|
7
|
-
const {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* 获取指定的 `Provider`
|
|
14
|
-
* @param id
|
|
15
|
-
*/
|
|
16
|
-
function getProvider(id?: ThirdParty) {
|
|
17
|
-
const provider = id ? providers.find(provider => provider.id === id) : providers[0];
|
|
18
|
-
if (!provider) {
|
|
19
|
-
throw new Error(`Provider '${id}' is not found.`);
|
|
20
|
-
}
|
|
21
|
-
return provider;
|
|
8
|
+
function getProvider(id?: ThirdParty) {
|
|
9
|
+
const { providers } = ctx.use();
|
|
10
|
+
const provider = id ? providers?.find(provider => provider.id === id) : providers?.[0];
|
|
11
|
+
if (!provider) {
|
|
12
|
+
throw new Error(`Provider '${id}' is not found.`);
|
|
22
13
|
}
|
|
23
|
-
|
|
24
|
-
return {
|
|
25
|
-
/**
|
|
26
|
-
* 前往登录
|
|
27
|
-
* @param id 唯一值
|
|
28
|
-
* @param options 登录时需要传递的参数
|
|
29
|
-
*/
|
|
30
|
-
async signIn(id: ThirdParty, options?: Recordable) {
|
|
31
|
-
const provider = getProvider(id);
|
|
32
|
-
const { type, authorization } = provider;
|
|
33
|
-
|
|
34
|
-
if (typeof authorization === 'function') {
|
|
35
|
-
return await authorization(options);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
if (type === 'oauth' || type === 'custom') {
|
|
39
|
-
const url = createUrl(provider);
|
|
40
|
-
window.location.replace(url);
|
|
41
|
-
}
|
|
42
|
-
},
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* 生成二维码
|
|
46
|
-
* @param id 第三方的唯一值
|
|
47
|
-
* @param options 生成二维码需要传递的参数
|
|
48
|
-
* @param options.id `getElementById`中指定的`id`
|
|
49
|
-
*/
|
|
50
|
-
renderQRCode(id: ThirdParty, options: { id: string } & Recordable) {
|
|
51
|
-
const provider = getProvider(id);
|
|
52
|
-
const { type, initQRCode } = provider;
|
|
53
|
-
|
|
54
|
-
if (type === 'oauth' || type === 'custom') {
|
|
55
|
-
const url = createUrl(provider);
|
|
56
|
-
initQRCode?.(url, options);
|
|
57
|
-
}
|
|
58
|
-
},
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* 认证
|
|
62
|
-
* @param id 第三方的唯一值
|
|
63
|
-
*/
|
|
64
|
-
async authentication(id: ThirdParty) {
|
|
65
|
-
const provider = getProvider(id);
|
|
66
|
-
const { type, callbackUrl } = provider;
|
|
67
|
-
|
|
68
|
-
// TODO 处理hash路由中的#
|
|
69
|
-
// 获取URL上的参数
|
|
70
|
-
const qs = window.location.href.split('?')?.[1] ?? '';
|
|
71
|
-
const params = new URLSearchParams(qs);
|
|
72
|
-
|
|
73
|
-
if (typeof callbackUrl === 'function') {
|
|
74
|
-
return await callbackUrl(Object.fromEntries(params.entries()), baseURL);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
if (type === 'oauth' || type === 'cas' || type === 'custom') {
|
|
78
|
-
const response = await fetch(`${baseURL}${callbackUrl}?${params.toString()}`);
|
|
79
|
-
return await response.json();
|
|
80
|
-
}
|
|
81
|
-
},
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
* 重定向至统一登录页
|
|
85
|
-
*/
|
|
86
|
-
redirect() {
|
|
87
|
-
const provider = providers.find(provider => provider.type === 'cas');
|
|
88
|
-
if (!provider) {
|
|
89
|
-
return;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
const url = createUrl(provider);
|
|
93
|
-
window.location.replace(url);
|
|
94
|
-
},
|
|
95
|
-
};
|
|
14
|
+
return provider;
|
|
96
15
|
}
|
|
97
16
|
|
|
98
17
|
/**
|
|
@@ -111,3 +30,76 @@ function createUrl(provider: ProviderUserConfig) {
|
|
|
111
30
|
|
|
112
31
|
return `${url.toString()}?${params.toString()}`;
|
|
113
32
|
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* 前往登录
|
|
36
|
+
* @param id 唯一值
|
|
37
|
+
* @param options 登录时需要传递的参数
|
|
38
|
+
*/
|
|
39
|
+
export async function signIn(id: ThirdParty, options?: Recordable) {
|
|
40
|
+
const provider = getProvider(id);
|
|
41
|
+
const { type, authorization } = provider;
|
|
42
|
+
|
|
43
|
+
if (typeof authorization === 'function') {
|
|
44
|
+
return await authorization(options);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (type === 'oauth' || type === 'custom') {
|
|
48
|
+
const url = createUrl(provider);
|
|
49
|
+
window.location.replace(url);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* 生成二维码
|
|
55
|
+
* @param id 第三方的唯一值
|
|
56
|
+
* @param options 生成二维码需要传递的参数
|
|
57
|
+
* @param options.id `getElementById`中指定的`id`
|
|
58
|
+
*/
|
|
59
|
+
export function renderQRCode(id: ThirdParty, options: { id: string } & Recordable) {
|
|
60
|
+
const provider = getProvider(id);
|
|
61
|
+
const { type, initQRCode } = provider;
|
|
62
|
+
|
|
63
|
+
if (type === 'oauth' || type === 'custom') {
|
|
64
|
+
const url = createUrl(provider);
|
|
65
|
+
initQRCode?.(url, options);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* 认证
|
|
71
|
+
* @param id 第三方的唯一值
|
|
72
|
+
*/
|
|
73
|
+
export async function authentication(id: ThirdParty) {
|
|
74
|
+
const provider = getProvider(id);
|
|
75
|
+
const { baseURL } = ctx.use();
|
|
76
|
+
const { type, callbackUrl } = provider;
|
|
77
|
+
|
|
78
|
+
// TODO 处理hash路由中的#
|
|
79
|
+
// 获取URL上的参数
|
|
80
|
+
const qs = window.location.href.split('?')?.[1] ?? '';
|
|
81
|
+
const params = new URLSearchParams(qs);
|
|
82
|
+
|
|
83
|
+
if (typeof callbackUrl === 'function') {
|
|
84
|
+
return await callbackUrl(Object.fromEntries(params.entries()), baseURL);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (type === 'oauth' || type === 'cas' || type === 'custom') {
|
|
88
|
+
const response = await fetch(`${baseURL}${callbackUrl}?${params.toString()}`);
|
|
89
|
+
return await response.json();
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* 重定向至统一登录页
|
|
95
|
+
*/
|
|
96
|
+
export function redirect() {
|
|
97
|
+
const { providers } = ctx.use();
|
|
98
|
+
const provider = providers?.find(provider => provider.type === 'cas');
|
|
99
|
+
if (!provider) {
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const url = createUrl(provider);
|
|
104
|
+
window.location.replace(url);
|
|
105
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -1,19 +1,23 @@
|
|
|
1
1
|
import type { ModuleOptions } from 'pubinfo';
|
|
2
2
|
import type { RouteRecordRaw } from 'vue-router';
|
|
3
|
-
import type { createAuth } from './core';
|
|
4
3
|
import type { AuthOptions } from './interface';
|
|
5
4
|
import { cleanup } from 'pubinfo';
|
|
5
|
+
import { ctx } from './context';
|
|
6
|
+
import { authentication, redirect } from './core';
|
|
6
7
|
import { PageAuth } from './pages/auth';
|
|
7
8
|
|
|
8
|
-
export function
|
|
9
|
-
const { authentication, redirect } = auth;
|
|
9
|
+
export function auth(options: AuthOptions): ModuleOptions {
|
|
10
10
|
const {
|
|
11
11
|
redirectTo = '/',
|
|
12
12
|
pages = {},
|
|
13
|
+
baseURL,
|
|
14
|
+
providers,
|
|
13
15
|
} = options;
|
|
14
|
-
const {
|
|
15
|
-
|
|
16
|
-
|
|
16
|
+
const { signIn = '/login' } = pages;
|
|
17
|
+
|
|
18
|
+
ctx.set({ baseURL, providers });
|
|
19
|
+
// 缓存以便 HMR 恢复
|
|
20
|
+
(globalThis as any).__PUBINFO__.authState = { baseURL, providers };
|
|
17
21
|
|
|
18
22
|
return {
|
|
19
23
|
name: 'pubinfo:auth',
|
package/src/interface.ts
CHANGED
|
@@ -13,11 +13,16 @@ export interface AuthOptions {
|
|
|
13
13
|
/** 默认登录页 */
|
|
14
14
|
signIn?: RouteLocationRaw
|
|
15
15
|
}
|
|
16
|
+
|
|
17
|
+
/** 接口的baseURL */
|
|
18
|
+
baseURL: string
|
|
19
|
+
|
|
20
|
+
providers?: ProviderConfig[]
|
|
16
21
|
}
|
|
17
22
|
|
|
18
|
-
export interface
|
|
23
|
+
export interface InternalContext {
|
|
19
24
|
/** 接口的baseURL */
|
|
20
|
-
baseURL
|
|
25
|
+
baseURL: string
|
|
21
26
|
|
|
22
27
|
providers?: ProviderConfig[]
|
|
23
28
|
}
|