temp
This commit is contained in:
parent
cb490470c1
commit
64c70ce527
3
.gitignore
vendored
3
.gitignore
vendored
@ -19,3 +19,6 @@ release/*
|
||||
.turbo
|
||||
|
||||
.env
|
||||
|
||||
pack-dist
|
||||
app.config.json5.envision
|
||||
|
22
config/pacage6/package.json
Normal file
22
config/pacage6/package.json
Normal file
@ -0,0 +1,22 @@
|
||||
{
|
||||
"name": "codecenter",
|
||||
"version": "1.0.0",
|
||||
"scripts": {
|
||||
"start": "pm2 start dist/app.mjs --name codecenter"
|
||||
},
|
||||
"dependencies": {
|
||||
"@kevisual/router": "^0.0.10-beta.1",
|
||||
"@kevisual/use-config": "^1.0.10",
|
||||
"ioredis": "^5.6.0",
|
||||
"minio": "^8.0.5",
|
||||
"pg": "^8.14.1",
|
||||
"sequelize": "^6.37.6",
|
||||
"sqlite3": "^5.1.7",
|
||||
"socket.io": "^4.8.1",
|
||||
"@msgpack/msgpack": "3.1.1",
|
||||
"pino": "^9.6.0",
|
||||
"pino-pretty": "^13.0.0",
|
||||
"pm2": "^6.0.5",
|
||||
"dotenv": "^16.4.7"
|
||||
}
|
||||
}
|
@ -5,6 +5,7 @@
|
||||
"type": "module",
|
||||
"main": "index.js",
|
||||
"author": "abearxiong",
|
||||
"basename": "/root/code-center",
|
||||
"scripts": {
|
||||
"watch": "rollup -c rollup.config.mjs -w",
|
||||
"dev": "cross-env NODE_ENV=development nodemon --delay 2.5 -e js,cjs,mjs --exec node dist/app.mjs",
|
||||
@ -13,11 +14,14 @@
|
||||
"build": "rimraf dist && rollup -c rollup.config.mjs",
|
||||
"deploy": "rsync -avz --delete ./dist/ --exclude='app.config.json5' light:~/apps/codecenter/dist",
|
||||
"deploy:sky": "rsync -avz --delete ./dist/ --exclude='app.config.json5' sky:~/kevisual/dist",
|
||||
"deploy:envision": "rsync -avz --delete ./dist/ --exclude='app.config.json5' envision:~/kevisual/dist",
|
||||
"clean": "rm -rf dist",
|
||||
"reload": "ssh light pm2 restart codecenter",
|
||||
"reload:sky": "ssh sky pm2 restart codecenter",
|
||||
"reload:envision": "ssh envision pm2 restart codecenter",
|
||||
"pub:me": "npm run build && npm run deploy && npm run reload",
|
||||
"pub:sky": "npm run build && npm run deploy:sky && npm run reload:sky",
|
||||
"pub:envision": "npm run build && npm run deploy:envision && npm run reload:envision",
|
||||
"start": "pm2 start dist/app.mjs --name codecenter",
|
||||
"release": "node ./config/release/index.mjs",
|
||||
"pub": "envision pack -p -u",
|
||||
@ -30,9 +34,7 @@
|
||||
"keywords": [],
|
||||
"types": "types/index.d.ts",
|
||||
"files": [
|
||||
"types",
|
||||
"dist",
|
||||
"src"
|
||||
"dist"
|
||||
],
|
||||
"license": "UNLICENSED",
|
||||
"dependencies": {
|
||||
|
@ -289,9 +289,19 @@
|
||||
|
||||
import { User, UserInit, UserServices } from '@kevisual/code-center-module/models';
|
||||
export { User, UserInit, UserServices };
|
||||
UserInit(null, null, {
|
||||
alter: true,
|
||||
logging: false,
|
||||
}).catch((e) => {
|
||||
console.error('User sync', e);
|
||||
});
|
||||
import { OrgInit } from '@kevisual/code-center-module/models';
|
||||
const init = async () => {
|
||||
await OrgInit(null, null, {
|
||||
alter: true,
|
||||
logging: false,
|
||||
}).catch((e) => {
|
||||
console.error('Org sync', e);
|
||||
});
|
||||
await UserInit(null, null, {
|
||||
alter: true,
|
||||
logging: false,
|
||||
}).catch((e) => {
|
||||
console.error('User sync', e);
|
||||
});
|
||||
};
|
||||
init();
|
||||
|
@ -18,6 +18,7 @@ export const addAuth = (app: App) => {
|
||||
.route({
|
||||
path: 'auth',
|
||||
id: 'auth',
|
||||
isDebug: true,
|
||||
})
|
||||
.define(async (ctx) => {
|
||||
const token = ctx.query.token;
|
||||
|
90
src/routes/app-manager/domain.ts
Normal file
90
src/routes/app-manager/domain.ts
Normal file
@ -0,0 +1,90 @@
|
||||
import { app } from '@/app.ts';
|
||||
import { AppModel } from './module/app.ts';
|
||||
import { AppDomainModel } from './module/app-domain.ts';
|
||||
|
||||
app
|
||||
.route({
|
||||
path: 'app',
|
||||
key: 'getDomainApp',
|
||||
})
|
||||
.define(async (ctx) => {
|
||||
const { domain } = ctx.query.data;
|
||||
// const query = {
|
||||
// }
|
||||
const domainInfo = await AppDomainModel.findOne({ where: { domain } });
|
||||
if (!domainInfo) {
|
||||
ctx.throw(404, 'app not found');
|
||||
}
|
||||
const app = await AppModel.findByPk(domainInfo.appId);
|
||||
if (!app) {
|
||||
ctx.throw(404, 'app not found');
|
||||
}
|
||||
ctx.body = app;
|
||||
return ctx;
|
||||
})
|
||||
.addTo(app);
|
||||
|
||||
app
|
||||
.route({
|
||||
path: 'app-domain',
|
||||
key: 'create',
|
||||
middleware: ['auth'],
|
||||
})
|
||||
.define(async (ctx) => {
|
||||
const tokenUser = ctx.state.tokenUser;
|
||||
const uid = tokenUser.uid;
|
||||
const { domain, appId } = ctx.query.data || {};
|
||||
if (!domain || !appId) {
|
||||
ctx.throw(400, 'domain and appId are required');
|
||||
}
|
||||
const domainInfo = await AppDomainModel.create({ domain, appId, uid });
|
||||
ctx.body = domainInfo;
|
||||
return ctx;
|
||||
})
|
||||
.addTo(app);
|
||||
|
||||
app
|
||||
.route({
|
||||
path: 'app-domain',
|
||||
key: 'update',
|
||||
middleware: ['auth'],
|
||||
})
|
||||
.define(async (ctx) => {
|
||||
const tokenUser = ctx.state.tokenUser;
|
||||
const uid = tokenUser.uid;
|
||||
const { id, domain, appId, status } = ctx.query.data || {};
|
||||
if (!domain && !id) {
|
||||
ctx.throw(400, 'domain and id are required at least one');
|
||||
}
|
||||
if (!status) {
|
||||
ctx.throw(400, 'status is required');
|
||||
}
|
||||
let domainInfo: AppDomainModel | null = null;
|
||||
if (id) {
|
||||
domainInfo = await AppDomainModel.findByPk(id);
|
||||
}
|
||||
if (!domainInfo && domain) {
|
||||
domainInfo = await AppDomainModel.findOne({ where: { domain, appId } });
|
||||
}
|
||||
if (!domainInfo) {
|
||||
ctx.throw(404, 'domain not found');
|
||||
}
|
||||
if (domainInfo.uid !== uid) {
|
||||
ctx.throw(403, 'domain must be owned by the user');
|
||||
}
|
||||
if (!domainInfo.checkCanUpdateStatus(status)) {
|
||||
ctx.throw(400, 'domain status can not be updated');
|
||||
}
|
||||
if (status) {
|
||||
domainInfo.status = status;
|
||||
}
|
||||
|
||||
if (appId) {
|
||||
domainInfo.appId = appId;
|
||||
}
|
||||
await domainInfo.save({ fields: ['status', 'appId'] });
|
||||
|
||||
ctx.body = domainInfo;
|
||||
return ctx;
|
||||
})
|
||||
.addTo(app);
|
@ -2,5 +2,6 @@ import './list.ts';
|
||||
import './user-app.ts';
|
||||
|
||||
import './public/index.ts';
|
||||
import './domain.ts';
|
||||
|
||||
export * from './module/index.ts';
|
||||
|
@ -140,6 +140,7 @@ app
|
||||
path: 'app',
|
||||
key: 'uploadFiles',
|
||||
middleware: ['auth'],
|
||||
isDebug: true,
|
||||
})
|
||||
.define(async (ctx) => {
|
||||
try {
|
||||
@ -264,23 +265,6 @@ app
|
||||
})
|
||||
.addTo(app);
|
||||
|
||||
app
|
||||
.route({
|
||||
path: 'app',
|
||||
key: 'getDomainApp',
|
||||
})
|
||||
.define(async (ctx) => {
|
||||
const { domain } = ctx.query.data;
|
||||
// const query = {
|
||||
// }
|
||||
const app = await AppModel.findOne({ where: { domain } });
|
||||
if (!app) {
|
||||
throw new CustomError('app not found');
|
||||
}
|
||||
ctx.body = app;
|
||||
return ctx;
|
||||
})
|
||||
.addTo(app);
|
||||
|
||||
app
|
||||
.route({
|
||||
|
64
src/routes/app-manager/module/app-domain.ts
Normal file
64
src/routes/app-manager/module/app-domain.ts
Normal file
@ -0,0 +1,64 @@
|
||||
import { sequelize } from '../../../modules/sequelize.ts';
|
||||
import { DataTypes, Model } from 'sequelize';
|
||||
export type DomainList = Partial<InstanceType<typeof AppDomainModel>>;
|
||||
|
||||
// 审核,通过,驳回
|
||||
const appDomainStatus = ['audit', 'auditReject', 'auditPending', 'running', 'stop'] as const;
|
||||
|
||||
type AppDomainStatus = (typeof appDomainStatus)[number];
|
||||
/**
|
||||
* 应用域名管理
|
||||
*/
|
||||
export class AppDomainModel extends Model {
|
||||
declare id: string;
|
||||
declare domain: string;
|
||||
declare appId: string;
|
||||
// 状态,
|
||||
declare status: AppDomainStatus;
|
||||
declare uid: string;
|
||||
|
||||
declare createdAt: Date;
|
||||
declare updatedAt: Date;
|
||||
|
||||
checkCanUpdateStatus(newStatus: AppDomainStatus) {
|
||||
// 原本是运行中,可以改为停止,原本是停止,可以改为运行。
|
||||
if (this.status === 'running' || this.status === 'stop') {
|
||||
return true;
|
||||
}
|
||||
// 原本是审核状态,不能修改。
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
AppDomainModel.init(
|
||||
{
|
||||
id: {
|
||||
type: DataTypes.UUID,
|
||||
primaryKey: true,
|
||||
defaultValue: DataTypes.UUIDV4,
|
||||
comment: 'id',
|
||||
},
|
||||
domain: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: false,
|
||||
unique: true,
|
||||
},
|
||||
appId: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: false,
|
||||
},
|
||||
uid: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
sequelize,
|
||||
tableName: 'kv_app_domain',
|
||||
paranoid: true,
|
||||
},
|
||||
);
|
||||
|
||||
AppDomainModel.sync({ alter: true, logging: false }).catch((e) => {
|
||||
console.error('AppDomainModel sync', e);
|
||||
});
|
@ -36,7 +36,6 @@ export class AppModel extends Model {
|
||||
declare title: string;
|
||||
declare description: string;
|
||||
declare version: string;
|
||||
declare domain: string;
|
||||
declare key: string;
|
||||
declare uid: string;
|
||||
declare pid: string;
|
||||
@ -69,10 +68,6 @@ AppModel.init(
|
||||
type: DataTypes.STRING,
|
||||
defaultValue: '',
|
||||
},
|
||||
domain: {
|
||||
type: DataTypes.STRING,
|
||||
defaultValue: '',
|
||||
},
|
||||
key: {
|
||||
type: DataTypes.STRING,
|
||||
// 和 uid 组合唯一
|
||||
|
@ -11,3 +11,5 @@ import './file/index.ts';
|
||||
import './micro-app/index.ts';
|
||||
|
||||
import './config/index.ts';
|
||||
|
||||
import './mark/index.ts';
|
||||
|
1
src/routes/mark/index.ts
Normal file
1
src/routes/mark/index.ts
Normal file
@ -0,0 +1 @@
|
||||
import './list.ts';
|
@ -44,26 +44,27 @@ app
|
||||
id: markModel.id,
|
||||
};
|
||||
} else {
|
||||
const [markModel, created] = await MarkModel.findOrCreate({
|
||||
where: {
|
||||
uid: tokenUser.id,
|
||||
puid: tokenUser.uid,
|
||||
title: dayjs().format('YYYY-MM-DD'),
|
||||
},
|
||||
defaults: {
|
||||
title: dayjs().format('YYYY-MM-DD'),
|
||||
uid: tokenUser.id,
|
||||
markType: 'wallnote',
|
||||
tags: ['daily'],
|
||||
},
|
||||
});
|
||||
ctx.body = {
|
||||
version: Number(markModel.version),
|
||||
updatedAt: markModel.updatedAt,
|
||||
createdAt: markModel.createdAt,
|
||||
id: markModel.id,
|
||||
created: created,
|
||||
};
|
||||
ctx.throw(400, 'id is required');
|
||||
// const [markModel, created] = await MarkModel.findOrCreate({
|
||||
// where: {
|
||||
// uid: tokenUser.id,
|
||||
// puid: tokenUser.uid,
|
||||
// title: dayjs().format('YYYY-MM-DD'),
|
||||
// },
|
||||
// defaults: {
|
||||
// title: dayjs().format('YYYY-MM-DD'),
|
||||
// uid: tokenUser.id,
|
||||
// markType: 'wallnote',
|
||||
// tags: ['daily'],
|
||||
// },
|
||||
// });
|
||||
// ctx.body = {
|
||||
// version: Number(markModel.version),
|
||||
// updatedAt: markModel.updatedAt,
|
||||
// createdAt: markModel.createdAt,
|
||||
// id: markModel.id,
|
||||
// created: created,
|
||||
// };
|
||||
}
|
||||
})
|
||||
.addTo(app);
|
||||
@ -87,24 +88,25 @@ app
|
||||
}
|
||||
ctx.body = markModel;
|
||||
} else {
|
||||
ctx.throw(400, 'id is required');
|
||||
// id 不存在,获取当天的title为 日期的一条数据
|
||||
const [markModel, created] = await MarkModel.findOrCreate({
|
||||
where: {
|
||||
uid: tokenUser.id,
|
||||
puid: tokenUser.uid,
|
||||
title: dayjs().format('YYYY-MM-DD'),
|
||||
},
|
||||
defaults: {
|
||||
title: dayjs().format('YYYY-MM-DD'),
|
||||
uid: tokenUser.id,
|
||||
markType: 'wallnote',
|
||||
tags: ['daily'],
|
||||
uname: tokenUser.username,
|
||||
puid: tokenUser.uid,
|
||||
version: 1,
|
||||
},
|
||||
});
|
||||
ctx.body = markModel;
|
||||
// const [markModel, created] = await MarkModel.findOrCreate({
|
||||
// where: {
|
||||
// uid: tokenUser.id,
|
||||
// puid: tokenUser.uid,
|
||||
// title: dayjs().format('YYYY-MM-DD'),
|
||||
// },
|
||||
// defaults: {
|
||||
// title: dayjs().format('YYYY-MM-DD'),
|
||||
// uid: tokenUser.id,
|
||||
// markType: 'wallnote',
|
||||
// tags: ['daily'],
|
||||
// uname: tokenUser.username,
|
||||
// puid: tokenUser.uid,
|
||||
// version: 1,
|
||||
// },
|
||||
// });
|
||||
// ctx.body = markModel;
|
||||
}
|
||||
})
|
||||
.addTo(app);
|
||||
|
@ -12,6 +12,7 @@ export const createCookie = (token: any, ctx: any) => {
|
||||
if (!domain) {
|
||||
return;
|
||||
}
|
||||
//TODO, 获取访问的 hostname, 如果访问的和 domain 的不一致,也创建cookie
|
||||
const browser = ctx.req.headers['user-agent'];
|
||||
const isBrowser = browser.includes('Mozilla'); // 浏览器
|
||||
if (isBrowser && ctx.res.cookie) {
|
||||
@ -50,11 +51,21 @@ export type ReqHeaders = {
|
||||
cookie: string; // 饼干
|
||||
};
|
||||
export const getSomeInfoFromReq = (ctx: any) => {
|
||||
const headers = ctx.req.headers as ReqHeaders;
|
||||
const userAgent = headers['user-agent'];
|
||||
const host = headers['host'];
|
||||
const ip = headers['x-forwarded-for'] || ctx.req.connection.remoteAddress;
|
||||
console.log('req headers', headers);
|
||||
const headers = ctx.req?.headers as ReqHeaders;
|
||||
if (!headers) {
|
||||
console.log('no req headers', ctx.req);
|
||||
return {
|
||||
'user-agent': '',
|
||||
browser: '',
|
||||
isBrowser: false,
|
||||
host: '',
|
||||
ip: '',
|
||||
headers: {},
|
||||
};
|
||||
}
|
||||
const userAgent = headers?.['user-agent'] || '';
|
||||
const host = headers?.['host'];
|
||||
const ip = headers?.['x-forwarded-for'] || ctx.req?.connection?.remoteAddress;
|
||||
return {
|
||||
'user-agent': userAgent,
|
||||
browser: userAgent,
|
||||
|
Loading…
x
Reference in New Issue
Block a user