mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-20 01:38:19 +08:00
+login-with-qq
This commit is contained in:
1 parent
09ced5cdff
commit
ac9dc00c6a
12 files changed
+133
-3
No files matched your search
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "hydrooj",
|
"name": "hydrooj",
|
||||||
"version": "2.12.13",
|
"version": "2.12.14",
|
||||||
"bin": "bin/hydrooj.js",
|
"bin": "bin/hydrooj.js",
|
||||||
"main": "dist/loader.js",
|
"main": "dist/loader.js",
|
||||||
"typings": "dist/loader.d.ts",
|
"typings": "dist/loader.d.ts",
|
||||||
|
|||||||
@@ -225,7 +225,7 @@ class OauthHandler extends Handler {
|
|||||||
class OauthCallbackHandler extends Handler {
|
class OauthCallbackHandler extends Handler {
|
||||||
async get(args: any) {
|
async get(args: any) {
|
||||||
let r;
|
let r;
|
||||||
if (global.Hydro.lib[`oauth_${args.type}`]) r = await global.Hydro.lib[`oauth_${args.type}`].callback(args);
|
if (global.Hydro.lib[`oauth_${args.type}`]) r = await global.Hydro.lib[`oauth_${args.type}`].callback.call(this, args);
|
||||||
else throw new UserFacingError('Oauth type');
|
else throw new UserFacingError('Oauth type');
|
||||||
const udoc = await user.getByEmail('system', r.email);
|
const udoc = await user.getByEmail('system', r.email);
|
||||||
if (udoc) {
|
if (udoc) {
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import cluster from 'cluster';
|
|||||||
import fs from 'fs-extra';
|
import fs from 'fs-extra';
|
||||||
import { argv } from 'yargs';
|
import { argv } from 'yargs';
|
||||||
import AdmZip from 'adm-zip';
|
import AdmZip from 'adm-zip';
|
||||||
|
import { } from './utils';
|
||||||
|
|
||||||
export * from './interface';
|
export * from './interface';
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { Collection } from 'mongodb';
|
|||||||
import { TokenDoc } from '../interface';
|
import { TokenDoc } from '../interface';
|
||||||
import * as db from '../service/db';
|
import * as db from '../service/db';
|
||||||
|
|
||||||
const coll: Collection<TokenDoc> = db.collection('token');
|
export const coll: Collection<TokenDoc> = db.collection('token');
|
||||||
|
|
||||||
export const TYPE_SESSION = 0;
|
export const TYPE_SESSION = 0;
|
||||||
export const TYPE_REGISTRATION = 2;
|
export const TYPE_REGISTRATION = 2;
|
||||||
@@ -88,6 +88,8 @@ export function delByUid(uid: number) {
|
|||||||
|
|
||||||
global.Hydro.postInit.push(ensureIndexes);
|
global.Hydro.postInit.push(ensureIndexes);
|
||||||
global.Hydro.model.token = {
|
global.Hydro.model.token = {
|
||||||
|
coll,
|
||||||
|
|
||||||
TYPE_SESSION,
|
TYPE_SESSION,
|
||||||
TYPE_CHANGEMAIL,
|
TYPE_CHANGEMAIL,
|
||||||
TYPE_OAUTH,
|
TYPE_OAUTH,
|
||||||
|
|||||||
@@ -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": []
|
||||||
|
}
|
||||||
@@ -17,6 +17,7 @@
|
|||||||
{ "path": "packages/login-with-github" },
|
{ "path": "packages/login-with-github" },
|
||||||
{ "path": "packages/login-with-google" },
|
{ "path": "packages/login-with-google" },
|
||||||
{ "path": "packages/login-with-osu" },
|
{ "path": "packages/login-with-osu" },
|
||||||
|
{ "path": "packages/login-with-qq" },
|
||||||
{ "path": "packages/migrate-vijos" },
|
{ "path": "packages/migrate-vijos" },
|
||||||
{ "path": "tsconfig.build.json" },
|
{ "path": "tsconfig.build.json" },
|
||||||
],
|
],
|
||||||
|
|||||||
Reference in new issue
Block a user