mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-20 01:38:19 +08:00
core: support oauth bind/unbind account (#971)
Co-authored-by: panda <panda_dtdyy@outlook.com>
This commit is contained in:
1 parent
1a8232899c
commit
536c697f4b
16 files changed
+393
-141
No files matched your search
@@ -0,0 +1,53 @@
|
||||
import { createHash, createHmac } from 'crypto';
|
||||
import {
|
||||
Context, ForbiddenError, Handler, Schema, Service,
|
||||
} from 'hydrooj';
|
||||
|
||||
// from https://www.svgrepo.com/svg/333610/telegram
|
||||
// eslint-disable-next-line max-len
|
||||
const icon = '<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="m20.665 3.717-17.73 6.837c-1.21.486-1.203 1.161-.222 1.462l4.552 1.42 10.532-6.645c.498-.303.953-.14.579.192l-8.533 7.701h-.002l.002.001-.314 4.692c.46 0 .663-.211.921-.46l2.211-2.15 4.599 3.397c.848.467 1.457.227 1.668-.785l3.019-14.228c.309-1.239-.473-1.8-1.282-1.434z"/></svg>';
|
||||
|
||||
export default class TelegramService extends Service {
|
||||
static Config = Schema.object({
|
||||
token: Schema.string().role('secret').required(),
|
||||
botLogin: Schema.string().required(),
|
||||
endpoint: Schema.string().default('https://api.telegram.org/bot'),
|
||||
});
|
||||
|
||||
constructor(ctx: Context, config: ReturnType<typeof TelegramService.Config>) {
|
||||
super(ctx, 'oauth.telegram');
|
||||
ctx.provideModule('oauth', 'telegram', {
|
||||
text: 'Login with Telegram',
|
||||
name: 'Telegram',
|
||||
icon,
|
||||
callback: async function callback({ payload }) {
|
||||
const parsed = JSON.parse(payload);
|
||||
const hash = parsed.hash;
|
||||
delete parsed.hash;
|
||||
const dataCheckString = Object.keys(parsed).sort().map((key) => (`${key}=${parsed[key]}`)).join('\n');
|
||||
const secretKey = createHash('sha256').update(config.token).digest();
|
||||
const dataCheckSum = createHmac('sha256', secretKey).update(dataCheckString).digest('hex');
|
||||
if (hash !== dataCheckSum) throw new ForbiddenError('Invalid hash');
|
||||
const {
|
||||
id, first_name, last_name, username, photo_url,
|
||||
} = parsed;
|
||||
const ret = {
|
||||
_id: id,
|
||||
email: `${id}@telegram.local`,
|
||||
bio: '',
|
||||
uname: [`${first_name} ${last_name}`, username, `telegram${id.toString()}`].filter((i) => i),
|
||||
avatar: `url:${photo_url}`,
|
||||
};
|
||||
if (!ret.email) throw new ForbiddenError("You don't have a verified email.");
|
||||
return ret;
|
||||
},
|
||||
async get(this: Handler) {
|
||||
this.response.body = { botLogin: config.botLogin };
|
||||
this.response.template = 'telegram_login.html';
|
||||
},
|
||||
});
|
||||
ctx.i18n.load('zh', {
|
||||
'Login With Telegram': '使用 Telegram 登录',
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user