| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119 |
- import { Hono } from 'hono'
- import type { Variables , WithAuth } from './middlewares.ts'
- // 配置信息
- const IM_APP_ID = Deno.env.get('IM_APP_ID');
- const IM_APP_KEY = Deno.env.get('IM_APP_KEY');
- const IM_APP_SIGN = Deno.env.get('IM_APP_SIGN');
- const RTC_APP_ID = Deno.env.get('RTC_APP_ID')
- const RTC_APP_KEY = Deno.env.get('RTC_APP_KEY')
- const hex = (buffer: ArrayBuffer): string => {
- const hexCodes = [];
- const view = new DataView(buffer);
- for (let i = 0; i < view.byteLength; i += 4) {
- const value = view.getUint32(i);
- const stringValue = value.toString(16);
- const padding = '00000000';
- const paddedValue = (padding + stringValue).slice(-padding.length);
- hexCodes.push(paddedValue);
- }
- return hexCodes.join('');
- };
- const generateRTCToken = async (
- channelId: string,
- userId: string
- ): Promise<{
- token: string;
- timestamp: number;
- }> => {
- const timestamp = Math.floor(Date.now() / 1000) + 3600 * 3;
- const encoder = new TextEncoder();
- const data = encoder.encode(`${RTC_APP_ID}${RTC_APP_KEY}${channelId}${userId}${timestamp}`);
- const hash = await crypto.subtle.digest('SHA-256', data);
- const token = hex(hash);
- return {
- token,
- timestamp
- }
- };
- const generateImToken = async (userId: string, role: string): Promise<{
- nonce: string;
- token: string;
- timestamp: number;
- }> => {
- const nonce = 'AK_4';
- const timestamp = Math.floor(Date.now() / 1000) + 3600 * 3;
- const pendingShaStr = `${IM_APP_ID}${IM_APP_KEY}${userId}${nonce}${timestamp}${role}`;
- const encoder = new TextEncoder();
- const data = encoder.encode(pendingShaStr);
- const hash = await crypto.subtle.digest('SHA-256', data);
- const token = hex(hash);
- return {
- nonce,
- token,
- timestamp
- }
- };
- export function createClassRoomRoutes(withAuth: WithAuth) {
- const tokenRoutes = new Hono<{ Variables: Variables }>()
- // 生成IM Token
- tokenRoutes.post('/im_token', withAuth, async (c) => {
- try {
- const { role } = await c.req.json()
- const user = c.get('user')
- if (!user || typeof user !== 'object' || !('id' in user)) {
- return c.json({ error: '用户信息无效' }, 401)
- }
-
- // 生成Token
- const { nonce, token , timestamp } = await generateImToken(user.id.toString(), role);
- return c.json({
- nonce,
- token,
- timestamp,
- appId: IM_APP_ID,
- appSign: IM_APP_SIGN,
- })
- } catch (error) {
- console.error('生成IM Token失败:', error)
- return c.json({ error: '生成IM Token失败' }, 500)
- }
- })
- // 生成RTC Token
- tokenRoutes.post('/rtc_token', withAuth, async (c) => {
- try {
- const { channelId } = await c.req.json()
- const user = c.get('user')
-
- if (!user || typeof user !== 'object' || !('id' in user)) {
- return c.json({ error: '用户信息无效' }, 401)
- }
-
- if (!RTC_APP_ID || !RTC_APP_KEY) {
- return c.json({ error: '服务配置不完整' }, 500)
- }
- // 生成Token
- const { token , timestamp } = await generateRTCToken(channelId, user.id.toString());
- return c.json({
- token,
- timestamp,
- appId: RTC_APP_ID,
- })
- } catch (error) {
- console.error('生成RTC Token失败:', error)
- return c.json({ error: '生成RTC Token失败' }, 500)
- }
- })
- return tokenRoutes
- }
|