新增 LinuxDo Oauth2 登录
This commit is contained in:
115
mail-worker/src/service/oauth-service.js
Normal file
115
mail-worker/src/service/oauth-service.js
Normal file
@@ -0,0 +1,115 @@
|
||||
import BizError from "../error/biz-error";
|
||||
import orm from "../entity/orm";
|
||||
import {oauth} from "../entity/oauth";
|
||||
import { eq } from 'drizzle-orm';
|
||||
import userService from "./user-service";
|
||||
import loginService from "./login-service";
|
||||
import cryptoUtils from "../utils/crypto-utils";
|
||||
|
||||
const oauthService = {
|
||||
|
||||
async bindUser(c, params) {
|
||||
|
||||
const { email, oauthUserId, code } = params;
|
||||
|
||||
const oauthRow = await this.getById(c, oauthUserId);
|
||||
|
||||
let userRow = await userService.selectByIdIncludeDel(c, oauthRow.userId);
|
||||
|
||||
if (userRow) {
|
||||
throw new BizError('用户已绑定有邮箱')
|
||||
}
|
||||
|
||||
await loginService.register(c, { email, password: cryptoUtils.genRandomPwd(), code }, true);
|
||||
|
||||
userRow = await userService.selectByEmail(c, email);
|
||||
|
||||
orm(c).update(oauth).set({ userId: userRow.userId }).where(eq(oauth.oauthUserId, oauthUserId)).run();
|
||||
const jwtToken = await loginService.login(c, { email, password: null }, true);
|
||||
|
||||
return { userInfo: oauthRow, token: jwtToken}
|
||||
},
|
||||
|
||||
async linuxDoLogin(c, params) {
|
||||
|
||||
const { code } = params;
|
||||
|
||||
let token = '';
|
||||
let userInfo = {}
|
||||
|
||||
const reqParams = new URLSearchParams()
|
||||
reqParams.append('client_id', c.env.linuxdo_client_id)
|
||||
reqParams.append('client_secret', c.env.linuxdo_client_secret)
|
||||
reqParams.append('code', code)
|
||||
reqParams.append('redirect_uri', c.env.linuxdo_callback_url)
|
||||
reqParams.append('grant_type', 'authorization_code')
|
||||
|
||||
const tokenRes = await fetch("https://connect.linux.do/oauth2/token", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
||||
body: reqParams.toString()
|
||||
})
|
||||
|
||||
if (!tokenRes.ok) {
|
||||
throw new BizError(tokenRes.statusText)
|
||||
}
|
||||
|
||||
token = await tokenRes.json()
|
||||
|
||||
const userRes = await fetch('https://connect.linux.do/api/user', {
|
||||
headers: {
|
||||
Authorization: 'Bearer ' + token.access_token
|
||||
}
|
||||
});
|
||||
|
||||
if (!userRes.ok) {
|
||||
throw new BizError(userRes.statusText)
|
||||
}
|
||||
|
||||
userInfo = await userRes.json();
|
||||
|
||||
userInfo.oauthUserId = String(userInfo.id);
|
||||
userInfo.active = userInfo.active ? 0 : 1;
|
||||
userInfo.silenced = userInfo.active ? 0 : 1;
|
||||
userInfo.trustLevel = userInfo.trust_level;
|
||||
userInfo.avatar = userInfo.avatar_url;
|
||||
|
||||
const oauthRow = await this.saveUser(c, userInfo);
|
||||
const userRow = await userService.selectByIdIncludeDel(c, oauthRow.userId);
|
||||
|
||||
if (!userRow) {
|
||||
return { userInfo: oauthRow, token: null }
|
||||
}
|
||||
|
||||
const JwtToken = await loginService.login(c, { email: userRow.email, password: null }, true);
|
||||
return { userInfo: oauthRow, token: JwtToken }
|
||||
},
|
||||
|
||||
async saveUser(c, userInfo) {
|
||||
|
||||
const userInfoRow = await this.getById(c, userInfo.oauthUserId);
|
||||
|
||||
if (!userInfoRow) {
|
||||
return await orm(c).insert(oauth).values(userInfo).returning().get();
|
||||
} else {
|
||||
return await orm(c).update(oauth).set(userInfo).where(eq(oauth.oauthUserId, userInfo.oauthUserId)).returning().get();
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
async getById(c, oauthUserId) {
|
||||
return await orm(c).select().from(oauth).where(eq(oauth.oauthUserId, oauthUserId)).get();
|
||||
},
|
||||
|
||||
async deleteByUserId(c, userId) {
|
||||
await orm(c).delete(oauth).where(eq(oauth.userId, userId)).run();
|
||||
},
|
||||
|
||||
//定时任务凌晨清除未绑定邮箱的oauth用户
|
||||
async clearNoBindOathUser(c) {
|
||||
await orm(c).delete(oauth).where(eq(oauth.userId, 0)).run();
|
||||
},
|
||||
|
||||
}
|
||||
|
||||
export default oauthService
|
||||
Reference in New Issue
Block a user