Files
console-dev/app/pages/oauth/callback.vue
T

155 lines
4.7 KiB
Vue

<script>
/**
* OAuth 回调恢复页:从服务端恢复授权会话,不从 URL 直接接纳登录令牌;结果只能进入登录或继续绑定流程。
*/
definePageMeta({
layout: `blank`,
});
import { useRuntimeConfig } from "#app";
import { toDisplayString } from "vue";
import { onMounted } from "vue";
import { onBeforeUnmount } from "vue";
import { createBlock } from "vue";
import { ref } from "vue";
import { withCtx } from "vue";
import { createCommentVNode } from "vue";
import { createElementBlock } from "vue";
import { createElementVNode } from "vue";
import { createTextVNode } from "vue";
import { unref } from "vue";
import { defineComponent } from "vue";
import { createVNode } from "vue";
import { openBlock } from "vue";
import { navigateTo } from "#app";
import { useHead } from "#app";
import { NuxtLink } from "#components";
import { useApi } from "~/lib/auth.js";
import { useAuth } from "~/lib/auth.js";
import button from "primevue/button";
import message from "primevue/message";
import { n as oauth_n } from "~/lib/oauth.js";
import { t as composables_t } from "~/lib/composables-2.js";
var w = {
class: `auth-card`,
},
T = defineComponent({
__name: `callback`,
setup(f) {
(composables_t({
layout: `blank`,
}),
useHead({
title: `恢复第三方登录`,
}));
let T = useApi(),
E = useAuth(),
D = ref(!1),
O = ref(``),
k = !0;
onBeforeUnmount(() => {
k = !1;
});
// 防止并发恢复;解析 OAuth 返回地址的允许来源,拒绝回调自循环,组件卸载后不再处理结果。
async function A() {
if (k && !D.value) {
((D.value = !0), (O.value = ``));
try {
let t = await T.get(`/oauth/token`);
if (!k) return;
let n = oauth_n(
t,
window.location.origin,
new URL(
String(
useRuntimeConfig().public.apiBase || window.location.origin,
),
window.location.origin,
).origin,
);
if (n.kind === `login`) {
E.loginWithJwt(n.jwt);
try {
sessionStorage.removeItem(`console-oauth-pending`);
} catch {}
await navigateTo(`/`);
} else if (n.kind === `bind`) {
if (new URL(n.url).pathname === `/oauth/callback`)
throw Error(`授权返回地址异常,请重新发起授权`);
window.location.replace(n.url);
} else throw Error(`授权会话已过期,请返回登录并重新授权`);
} catch (e) {
k && (O.value = e instanceof Error ? e.message : `恢复登录失败`);
} finally {
k && (D.value = !1);
}
}
}
return (
onMounted(A),
// 恢复状态、重试按钮与返回登录入口共用 A;展示页不从查询参数直接接纳 JWT。
(e, n) => {
let r = message,
a = button,
f = NuxtLink;
return (
openBlock(),
createElementBlock(`section`, w, [
(n[1] ||= createElementVNode(`h1`, null, `恢复第三方登录`, -1)),
(n[2] ||= createElementVNode(
`p`,
null,
`正在验证授权会话。`,
-1,
)),
unref(O)
? (openBlock(),
createBlock(
r,
{
key: 0,
severity: `error`,
closable: !1,
},
{
default: withCtx(() => [
createTextVNode(toDisplayString(unref(O)), 1),
]),
_: 1,
},
))
: createCommentVNode(``, !0),
createVNode(
a,
{
label: `重新验证`,
loading: unref(D),
onClick: A,
},
null,
8,
[`loading`],
),
createElementVNode(`p`, null, [
createVNode(
f,
{
to: `/login`,
},
{
default: withCtx(() => [
...(n[0] ||= [createTextVNode(`返回登录`, -1)]),
]),
_: 1,
},
),
]),
])
);
}
);
},
});
export {};
export default T;
</script>