import assert from "assert"; /** * OAuth 授权页面组件 */ export default OakComponent({ // Virtual Component isList: false, filters: [], properties: { onUnLogin: null, }, data: { clientInfo: null, loading: true, userInfo: null, hasError: false, errorMsg: '', name: '', nickname: '', mobile: '', avatarUrl: '', response_type: '', client_id: '', redirect_uri: '', scope: '', state: '', }, lifetimes: { async ready() { const searchParams = new URLSearchParams(window.location.search); const clientId = searchParams.get('client_id') || ''; const responseType = searchParams.get('response_type') || ''; const redirectUri = searchParams.get('redirect_uri') || ''; const scope = searchParams.get('scope') || ''; const state = searchParams.get('state') || ''; //判断是否允许oauth登录 const application = this.features.application.getApplication(); const { result: applicationPassports } = await this.features.cache.exec('getApplicationPassports', { applicationId: application.id }); const oauthPassport = applicationPassports?.find((ele) => ele.passport?.type === 'oauth'); const oauthIds = oauthPassport?.config?.oauthIds; let allowOauth = false; if (clientId) { const { data: [oauthProvider] } = await this.features.cache.refresh('oauthProvider', { data: { id: 1, clientId: 1, systemId: 1, }, filter: { clientId, systemId: application.systemId, } }); if (oauthProvider?.id && oauthIds?.length > 0 && oauthIds.includes(oauthProvider?.id)) { allowOauth = true; } } if (!allowOauth) { this.setState({ hasError: true, errorMsg: 'oauth.login', }); this.setState({ loading: false }); return; } this.setState({ client_id: clientId, response_type: responseType, redirect_uri: redirectUri, scope: scope, state: state, }); // load userinfo const userId = this.features.token.getUserId(true); if (!userId) { // const params = new URLSearchParams(); // params.set('response_type', responseType || ""); // params.set('client_id', clientId || ""); // params.set('redirect_uri', redirectUri || ""); // params.set('scope', scope || ""); // params.set('state', state || ""); // const redirectUrl = `/login/oauth/authorize?${params.toString()}`; // console.log('Not logged in, redirecting to login page:', redirectUrl); // const encoded = btoa(encodeURIComponent(redirectUrl)); // this.features.navigator.navigateTo({ // url: `/login?redirect=${encoded}`, // }, undefined, true); if (!this.props.onUnLogin) { console.error('用户未登录,请在使用Oauth授权组件时配置onUnLogin回调函数'); return; } this.props.onUnLogin({ response_type: responseType, client_id: clientId, redirect_uri: redirectUri, scope: scope, state: state, }); return; } const userInfo = this.features.token.getUserInfo(); const { mobile } = (userInfo?.mobile$user && userInfo?.mobile$user[0]) || (userInfo?.user$ref && userInfo?.user$ref[0] && userInfo?.user$ref[0].mobile$user && userInfo?.user$ref[0].mobile$user[0]) || {}; const extraFile = userInfo?.extraFile$entity?.find((ele) => ele.tag1 === 'avatar'); const avatarUrl = this.features.extraFile.getUrl(extraFile); this.setState({ userInfo: userId ? this.features.token.getUserInfo() : null, name: userInfo?.name || '', nickname: userInfo?.nickname || '', mobile: mobile || '', avatarUrl, }); // end load userinfo if (!clientId) { this.setState({ hasError: true, errorMsg: 'oauth.authorize.error.missing_client_id', }); this.setState({ loading: false }); return; } if (!responseType) { this.setState({ hasError: true, errorMsg: 'oauth.authorize.error.missing_response_type', }); this.setState({ loading: false }); return; } this.features.cache.exec("getOAuthClientInfo", { client_id: clientId, currentUserId: userId, }).then((clientInfo) => { if (!clientInfo.result) { this.setState({ loading: false }); this.setState({ hasError: true, errorMsg: 'oauth.authorize.error.invalid_client_id', }); } else { this.setState({ clientInfo: clientInfo.result.data, }); if (clientInfo.result.alreadyAuth) { // 已经授权过,直接跳转 this.handleGrant(); } else { this.setState({ loading: false }); } } }).catch((err) => { this.setState({ loading: false }); console.error('Error loading OAuth client info:', err); this.setState({ hasError: true, errorMsg: err.message || 'oauth.authorize.error.unknown', }); }); }, }, methods: { handleGrant() { this.callAspectAuthorize("grant"); }, handleDeny() { this.callAspectAuthorize("deny"); }, callAspectAuthorize(action) { this.features.cache.exec("authorize", { response_type: this.state.response_type || "", client_id: this.state.client_id || "", redirect_uri: this.state.redirect_uri || "", scope: this.state.scope || "", state: this.state.state || "", action: action, }).then((result) => { const { redirectUri } = result.result; assert(redirectUri, 'redirectUri should be present in authorize result'); window.location.replace(redirectUri); }).catch((err) => { console.error('Error during OAuth authorization:', err); this.setState({ hasError: true, errorMsg: err.message || 'oauth.authorize.error.unknown', }); }); } }, });