- Introduced `cnb-login` route to handle user login via CNB token. - Created `CnbServices` class for managing CNB user interactions. - Added `findByCnbId` method in the User model to retrieve users by CNB ID. - Updated error handling to provide more structured error messages. - Enhanced user creation logic to handle CNB users. - Added tests for the new CNB login functionality.
62 lines
2.3 KiB
TypeScript
62 lines
2.3 KiB
TypeScript
import { Config } from '../models/model.ts';
|
|
import { CustomError } from '@kevisual/router';
|
|
import { redis, db, schema } from '@/app.ts';
|
|
import { eq, and } from 'drizzle-orm';
|
|
import { UserPermission, UserPermissionOptions } from '@kevisual/permission';
|
|
|
|
export class ShareConfigService {
|
|
/**
|
|
* 获取分享的配置
|
|
* @param key 配置的key
|
|
* @param username 分享者的username
|
|
* @returns 配置
|
|
*/
|
|
static async getShareConfig(key: string, username: string, options: UserPermissionOptions) {
|
|
const shareCacheConfigString = await redis.get(`config:share:${username}:${key}`);
|
|
let shareCacheConfig: Config;
|
|
try {
|
|
shareCacheConfig = JSON.parse(shareCacheConfigString);
|
|
} catch (e) {
|
|
await redis.set(`config:share:${username}:${key}`, '', 'EX', 0); // 删除缓存
|
|
throw new CustomError(400, { message: 'config parse error' });
|
|
}
|
|
const owner = username;
|
|
if (shareCacheConfig) {
|
|
const permission = new UserPermission({ permission: (shareCacheConfig?.data as any)?.permission, owner });
|
|
const result = permission.checkPermissionSuccess(options);
|
|
if (!result.success) {
|
|
throw new CustomError(403, { message: 'no permission' });
|
|
}
|
|
return shareCacheConfig;
|
|
}
|
|
const users = await db.select()
|
|
.from(schema.cfUser)
|
|
.where(eq(schema.cfUser.username, username))
|
|
.limit(1);
|
|
const user = users[0];
|
|
if (!user) {
|
|
throw new CustomError(404, { message: 'user not found' });
|
|
}
|
|
const configs = await db.select()
|
|
.from(schema.kvConfig)
|
|
.where(and(eq(schema.kvConfig.key, key), eq(schema.kvConfig.uid, user.id)))
|
|
.limit(1);
|
|
const config = configs[0];
|
|
if (!config) {
|
|
throw new CustomError(404, { message: 'config not found' });
|
|
}
|
|
const permission = new UserPermission({ permission: (config?.data as any)?.permission, owner });
|
|
const result = permission.checkPermissionSuccess(options);
|
|
if (!result.success) {
|
|
throw new CustomError(403, { message: 'no permission' });
|
|
}
|
|
await redis.set(`config:share:${username}:${key}`, JSON.stringify(config), 'EX', 60 * 60 * 24 * 7); // 7天
|
|
return config;
|
|
}
|
|
static async expireShareConfig(key: string, username: string) {
|
|
if (key && username) {
|
|
await redis.set(`config:share:${username}:${key}`, '', 'EX', 1);
|
|
}
|
|
}
|
|
}
|