- Replaced Sequelize models with Drizzle ORM for app and app list management. - Updated routes in app-manager to utilize new database queries. - Removed obsolete Sequelize model files for app, app list, and app domain. - Introduced new helper functions for app and app domain management. - Enhanced user app management with improved file handling and user migration. - Adjusted public API routes to align with new database structure. - Implemented caching mechanisms for domain management.
171 lines
4.2 KiB
TypeScript
171 lines
4.2 KiB
TypeScript
import { app, db, schema } from '@/app.ts';
|
||
import { Org } from '@/models/org.ts';
|
||
import { User } from '@/models/user.ts';
|
||
import { sql, eq } from 'drizzle-orm';
|
||
|
||
app
|
||
.route({
|
||
path: 'org',
|
||
key: 'list',
|
||
middleware: ['auth'],
|
||
})
|
||
.define(async (ctx) => {
|
||
const tokenUser = ctx.state.tokenUser;
|
||
const list = await db
|
||
.select()
|
||
.from(schema.cfOrgs)
|
||
.where(sql`${schema.cfOrgs.users} @> ${JSON.stringify([{ uid: tokenUser.id }])}::jsonb`)
|
||
.orderBy(sql`${schema.cfOrgs.updatedAt} DESC`);
|
||
|
||
ctx.body = list;
|
||
return ctx;
|
||
})
|
||
.addTo(app);
|
||
|
||
app
|
||
.route({
|
||
path: 'org',
|
||
key: 'update',
|
||
middleware: ['auth-admin'],
|
||
})
|
||
.define(async (ctx) => {
|
||
const tokenUser = ctx.state.tokenUser;
|
||
// username 为org的名字,在用户表中也是唯一的
|
||
const { username, description, id } = ctx.query.data;
|
||
if (!username) {
|
||
ctx.throw('username is required');
|
||
}
|
||
if (id) {
|
||
const org = await Org.findByPk(id);
|
||
if (!org) {
|
||
ctx.throw('org not found');
|
||
}
|
||
org.description = description;
|
||
await db.update(schema.cfOrgs).set({ description }).where(eq(schema.cfOrgs.id, org.id));
|
||
const user = await User.findOne({ username });
|
||
if (user) {
|
||
user.description = description;
|
||
await user.save();
|
||
}
|
||
ctx.body = {
|
||
id: user?.id,
|
||
username: user?.username,
|
||
description: user?.description,
|
||
};
|
||
return;
|
||
}
|
||
const user = await User.findByPk(tokenUser.id);
|
||
if (!user) {
|
||
ctx.throw('user not found');
|
||
}
|
||
user.setTokenUser(tokenUser);
|
||
const orgs = await user.getOrgs();
|
||
if (!orgs.includes('admin')) {
|
||
ctx.throw('Permission denied');
|
||
}
|
||
const newUser = await User.createOrg(username, tokenUser.id, description);
|
||
ctx.body = {
|
||
id: newUser.id,
|
||
username: newUser.username,
|
||
description: newUser.description,
|
||
};
|
||
})
|
||
.addTo(app);
|
||
|
||
app
|
||
.route({
|
||
path: 'org',
|
||
key: 'delete',
|
||
middleware: ['auth'],
|
||
})
|
||
.define(async (ctx) => {
|
||
const tokenUser = ctx.state.tokenUser;
|
||
const id = ctx.query.id;
|
||
if (!id) {
|
||
ctx.throw('id is required');
|
||
}
|
||
const org = await Org.findByPk(id);
|
||
if (!org) {
|
||
ctx.throw('org not found');
|
||
}
|
||
const username = org.username;
|
||
const users = org.users;
|
||
const owner = users.find((u) => u.role === 'owner');
|
||
if (owner.uid !== tokenUser.id) {
|
||
ctx.throw('Permission denied');
|
||
}
|
||
await db.delete(schema.cfOrgs).where(eq(schema.cfOrgs.id, org.id));
|
||
const orgUser = await User.findOne({ username });
|
||
if (orgUser) {
|
||
await db.delete(schema.cfUser).where(eq(schema.cfUser.id, orgUser.id));
|
||
}
|
||
ctx.body = 'success';
|
||
})
|
||
.addTo(app);
|
||
|
||
app
|
||
.route({
|
||
path: 'org',
|
||
key: 'get',
|
||
middleware: ['auth'],
|
||
})
|
||
.define(async (ctx) => {
|
||
const tokenUser = ctx.state.tokenUser;
|
||
const id = ctx.query.id;
|
||
if (!id) {
|
||
ctx.throw('id is required');
|
||
}
|
||
const org = await Org.findByPk(id);
|
||
if (!org) {
|
||
ctx.throw('org not found');
|
||
}
|
||
const usersIds = org.users;
|
||
const me = usersIds.find((u) => u.uid === tokenUser.id);
|
||
if (!me) {
|
||
ctx.throw('Permission denied');
|
||
}
|
||
const orgGetUser = await org.getUsers();
|
||
ctx.body = {
|
||
org,
|
||
users: orgGetUser.users,
|
||
};
|
||
})
|
||
.addTo(app);
|
||
|
||
app
|
||
.route({
|
||
path: 'org',
|
||
key: 'hasUser',
|
||
middleware: ['auth'],
|
||
description: '判断当前username这个组织,是否在当前用户的组织中。如果有,返回当前组织的用户信息,否则返回null',
|
||
})
|
||
.define(async (ctx) => {
|
||
const tokenUser = ctx.state.tokenUser;
|
||
const { username } = ctx.query.data;
|
||
const user = await User.findByPk(tokenUser.id);
|
||
if (!user) {
|
||
ctx.throw('user not found');
|
||
}
|
||
user.setTokenUser(tokenUser);
|
||
const userOrgs = await user.hasUser(username, true);
|
||
if (!userOrgs) {
|
||
ctx.body = {
|
||
uid: null,
|
||
};
|
||
return;
|
||
}
|
||
const usernameUser = await User.findOne({ username });
|
||
|
||
if (!usernameUser) {
|
||
ctx.body = {
|
||
uid: null,
|
||
};
|
||
return;
|
||
}
|
||
ctx.body = {
|
||
uid: usernameUser.id,
|
||
user: usernameUser,
|
||
};
|
||
})
|
||
.addTo(app);
|