add reg, hw will use imei instead of token

This commit is contained in:
Paul Pan 2023-12-03 00:11:22 +08:00
parent 7b52bb9da9
commit e15bdc192a
4 changed files with 86 additions and 24 deletions

View File

@ -4,6 +4,60 @@ import { IsValidUUID } from '../lib/uuid';
import { Status } from '../lib/status'; import { Status } from '../lib/status';
import { Wrap } from '../lib/wrapper'; import { Wrap } from '../lib/wrapper';
async function CMDBind(env: Env, chat_id: number, text: string): Promise<Response> {
const uuid = text.split('CMD:BIND:')[1];
// validate uuid
if (!IsValidUUID(uuid)) {
await new Bot(env.TG_BOT_TOKEN).send(chat_id, '[BOT] Invalid UUID (1)');
return Wrap(Status.BadRequest, 'Invalid UUID (1)');
}
// NOTE: since KV is eventually consistent, these checks might not be correct
// check if chat_id is already bounded to uuid
if ((await env.KV.get(`C:${chat_id}`)) !== null) {
await new Bot(env.TG_BOT_TOKEN).send(chat_id, '[BOT] Already Bounded');
return Wrap(Status.OK, 'Already bounded');
}
// check if uuid is already bounded to chat_id
if ((await env.KV.get(`U:${uuid}`)) !== null) {
await new Bot(env.TG_BOT_TOKEN).send(chat_id, '[BOT] Invalid UUID (2)');
return Wrap(Status.OK, 'Invalid UUID (2)');
}
// bind
await env.KV.put(`U:${uuid}`, chat_id.toString());
await env.KV.put(`C:${chat_id}`, uuid);
await new Bot(env.TG_BOT_TOKEN).send(chat_id, '[BOT] Bind Success');
return Wrap(Status.OK, 'Bind Success');
}
async function CMDUnbind(env: Env, chat_id: number, text: string): Promise<Response> {
// check if chat_id is bounded
const uuid = await env.KV.get(`C:${chat_id}`);
if (uuid === null) {
await new Bot(env.TG_BOT_TOKEN).send(chat_id, '[BOT] Not Bounded');
return Wrap(Status.OK, 'Not bounded');
}
// unbind
await env.KV.delete(`U:${uuid}`);
await env.KV.delete(`C:${chat_id}`);
await new Bot(env.TG_BOT_TOKEN).send(chat_id, '[BOT] Unbind Success');
return Wrap(Status.OK, 'Unbind Success');
}
type CMDHandler = (env: Env, chat_id: number, text: string) => Promise<Response>;
const cmd: { [prefix: string]: CMDHandler } = {
'CMD:BIND:': CMDBind,
'CMD:UNBIND': CMDUnbind,
// TODO: CMD:SEND:
};
export async function FuncHook(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> { export async function FuncHook(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
if (request.method !== 'POST') return Wrap(Status.BadRequest, 'Only POST method is allowed'); if (request.method !== 'POST') return Wrap(Status.BadRequest, 'Only POST method is allowed');
@ -18,25 +72,11 @@ export async function FuncHook(request: Request, env: Env, ctx: ExecutionContext
console.debug(`[Hook] ${chat_id} ${text}`); console.debug(`[Hook] ${chat_id} ${text}`);
if (text.startsWith('BIND:')) { for (const prefix in cmd) {
const uuid = text.split(':')[1]; if (text.startsWith(prefix)) {
if (!IsValidUUID(uuid)) return Wrap(Status.BadRequest, 'Invalid UUID'); return cmd[prefix](env, chat_id, text);
await env.KV.put(uuid, chat_id.toString());
await new Bot(env.TG_BOT_TOKEN).send(chat_id, '[BOT] Bind Success');
return Wrap(Status.OK, 'Bind successfully');
} }
if (text.startsWith('UNBIND:')) {
const uuid = text.split(':')[1];
if (!IsValidUUID(uuid)) return Wrap(Status.BadRequest, 'Invalid UUID');
await env.KV.delete(uuid);
await new Bot(env.TG_BOT_TOKEN).send(chat_id, '[BOT] Unbind Success');
return Wrap(Status.OK, 'Unbind successfully');
} }
// TODO: Handle "SEND:" command
// TODO: Handle Cited Message (Text or Voice) with command
return Wrap(Status.OK, 'Nothing Executed'); return Wrap(Status.OK, 'Nothing Executed');
} }

View File

@ -1,18 +1,20 @@
import { Bot } from '../lib/bot'; import { Bot } from '../lib/bot';
import { Env } from '../index'; import { Env } from '../index';
import { IsValidUUID } from '../lib/uuid';
import { Status } from '../lib/status'; import { Status } from '../lib/status';
import { Wrap } from '../lib/wrapper'; import { Wrap } from '../lib/wrapper';
export async function FuncPush(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> { export async function FuncPush(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
if (request.method !== 'POST') return Wrap(Status.BadRequest, 'Only POST method is allowed'); if (request.method !== 'POST') return Wrap(Status.BadRequest, 'Only POST method is allowed');
const token = request.headers.get('X-Auth-Token'); const imei = request.headers.get('X-Auth-Token');
if (!token) return Wrap(Status.BadRequest, 'Missing X-Auth-Token header'); if (!imei) return Wrap(Status.BadRequest, 'Missing X-Auth-Token header');
if (!IsValidUUID(token)) return Wrap(Status.BadRequest, 'Invalid Token'); if (imei.length < 15 || imei.length > 17) return Wrap(Status.BadRequest, 'Invalid Token (1)');
const chat_id = await env.KV.get(token); const uuid = await env.KV.get(`I:${imei}`);
if (!chat_id) return Wrap(Status.BadRequest, 'Invalid Token'); if (!uuid) return Wrap(Status.BadRequest, 'Invalid Token (2)');
const chat_id = await env.KV.get(`U:${uuid}`);
if (!chat_id) return Wrap(Status.BadRequest, 'Invalid Token (3)');
const bot = new Bot(env.TG_BOT_TOKEN); const bot = new Bot(env.TG_BOT_TOKEN);
const message = await request.text(); const message = await request.text();

18
src/func/reg.ts Normal file
View File

@ -0,0 +1,18 @@
import { Env } from '../index';
import { GenUUID } from '../lib/uuid';
import { Status } from '../lib/status';
import { Wrap } from '../lib/wrapper';
export async function FuncReg(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
if (request.method !== 'POST') return Wrap(Status.BadRequest, 'Only POST method is allowed');
const imei = await request.text();
if (!imei || imei.length < 15 || imei.length > 17) return Wrap(Status.BadRequest, 'Invalid IMEI');
const token = await env.KV.get(`I:${imei}`);
if (token) return Wrap(Status.OK, token);
const new_token = GenUUID();
await env.KV.put(`I:${imei}`, new_token);
return Wrap(Status.OK, new_token);
}

View File

@ -1,6 +1,7 @@
import { NotFound } from './lib/wrapper'; import { NotFound } from './lib/wrapper';
import { FuncPush } from './func/push'; import { FuncPush } from './func/push';
import { FuncHook } from './func/hook'; import { FuncHook } from './func/hook';
import { FuncReg } from './func/reg';
export interface Env { export interface Env {
KV: KVNamespace; KV: KVNamespace;
@ -14,6 +15,7 @@ export type Handler = (request: Request, env: Env, ctx: ExecutionContext) => Pro
const routes: { [page: string]: Handler } = { const routes: { [page: string]: Handler } = {
'/push': FuncPush, '/push': FuncPush,
'/hook': FuncHook, '/hook': FuncHook,
'/reg': FuncReg,
}; };
export default { export default {