+login-with-qq
parent
09ced5cdff
commit
ac9dc00c6a
@ -0,0 +1 @@
|
||||
# Login-With-QQ
|
@ -0,0 +1,36 @@
|
||||
import 'hydrooj';
|
||||
import 'hydrooj/dist/utils';
|
||||
|
||||
async function get() {
|
||||
const { system, token } = global.Hydro.model;
|
||||
const secret = String.random(8);
|
||||
const [id, [tokenId]] = await Promise.all([
|
||||
system.get('login-with-qq.id'),
|
||||
token.add(token.TYPE_OAUTH, 600, { redirect: this.request.referer, secret }),
|
||||
]);
|
||||
const message = `Please send "login ${secret}" to qq account ${id}, and then use the link below:\n /oauth/qq/callback?state=${tokenId}`;
|
||||
this.response.body = {
|
||||
code: tokenId, secret, id, message,
|
||||
};
|
||||
}
|
||||
|
||||
async function callback({ state }) {
|
||||
const { token } = global.Hydro.model;
|
||||
const { InvalidTokenError } = global.Hydro.error;
|
||||
const s = await token.get(state, token.TYPE_OAUTH);
|
||||
if (!s || !s.email) throw new InvalidTokenError(state);
|
||||
const ret = {
|
||||
email: s.email,
|
||||
bio: '',
|
||||
uname: [s.username],
|
||||
};
|
||||
this.response.redirect = s.redirect;
|
||||
await token.del(s._id, token.TYPE_OAUTH);
|
||||
return ret;
|
||||
}
|
||||
|
||||
global.Hydro.lib.oauth_qq = {
|
||||
text: 'Login with QQ',
|
||||
callback,
|
||||
get,
|
||||
};
|
@ -0,0 +1 @@
|
||||
Login with QQ: 使用 QQ 登录
|
@ -0,0 +1,19 @@
|
||||
{
|
||||
"name": "@hydrooj/login-with-qq",
|
||||
"version": "0.0.1",
|
||||
"main": "package.json",
|
||||
"repository": "git@github.com:hydro-dev/Hydro.git",
|
||||
"author": "undefined <masnn0@outlook.com>",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"lint": "eslint lib.ts service.ts --fix",
|
||||
"build": "tsc"
|
||||
},
|
||||
"dependencies": {
|
||||
"hydrooj": "^2.12.1",
|
||||
"ws": "^7.3.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/ws": "^7.2.6"
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
import { } from 'hydrooj';
|
||||
import WebSocket from 'ws';
|
||||
|
||||
export async function postInit() {
|
||||
const { system, token } = global.Hydro.model;
|
||||
const [url, accessToken] = await system.getMany(['login-with-qq.url', 'login-with-qq.token']);
|
||||
if (!url) return;
|
||||
const headers: Record<string, string> = {};
|
||||
if (accessToken) headers.Authorization = `Bearer ${accessToken}`;
|
||||
const socket = new WebSocket(url, { headers });
|
||||
socket.on('error', console.error);
|
||||
socket.on('message', async (message) => {
|
||||
const payload = JSON.parse(message.toString());
|
||||
if (payload.post_type !== 'message') return;
|
||||
if (payload.message.startsWith('login ')) {
|
||||
const secret = payload.message.split(' ')[1];
|
||||
await token.coll.updateOne(
|
||||
{ secret, tokenType: token.TYPE_OAUTH },
|
||||
{
|
||||
$set: {
|
||||
email: `${payload.sender.user_id}@qq.com`,
|
||||
username: payload.sender.nickname,
|
||||
},
|
||||
},
|
||||
);
|
||||
}
|
||||
});
|
||||
await new Promise((resolve) => {
|
||||
socket.once('open', () => {
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
global.Hydro.postInit.push(postInit);
|
@ -0,0 +1,15 @@
|
||||
url:
|
||||
type: text
|
||||
category: system
|
||||
desc: cqhttp ws api url
|
||||
name: url
|
||||
token:
|
||||
type: text
|
||||
category: system
|
||||
desc: cqhttp token
|
||||
name: token
|
||||
id:
|
||||
type: text
|
||||
category: system
|
||||
desc: QQ account id
|
||||
name: id
|
@ -0,0 +1,19 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es2019",
|
||||
"module": "commonjs",
|
||||
"esModuleInterop": true,
|
||||
"moduleResolution": "node",
|
||||
"declaration": true,
|
||||
"sourceMap": true,
|
||||
"composite": true,
|
||||
"strictBindCallApply": true,
|
||||
"experimentalDecorators": true,
|
||||
"outDir": ".",
|
||||
"rootDir": "."
|
||||
},
|
||||
"include": [
|
||||
"*.ts"
|
||||
],
|
||||
"exclude": []
|
||||
}
|
Loading…
Reference in New Issue