temp
This commit is contained in:
parent
cb490470c1
commit
64c70ce527
3
.gitignore
vendored
3
.gitignore
vendored
@ -19,3 +19,6 @@ release/*
|
|||||||
.turbo
|
.turbo
|
||||||
|
|
||||||
.env
|
.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",
|
"type": "module",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"author": "abearxiong",
|
"author": "abearxiong",
|
||||||
|
"basename": "/root/code-center",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"watch": "rollup -c rollup.config.mjs -w",
|
"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",
|
"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",
|
"build": "rimraf dist && rollup -c rollup.config.mjs",
|
||||||
"deploy": "rsync -avz --delete ./dist/ --exclude='app.config.json5' light:~/apps/codecenter/dist",
|
"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: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",
|
"clean": "rm -rf dist",
|
||||||
"reload": "ssh light pm2 restart codecenter",
|
"reload": "ssh light pm2 restart codecenter",
|
||||||
"reload:sky": "ssh sky 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:me": "npm run build && npm run deploy && npm run reload",
|
||||||
"pub:sky": "npm run build && npm run deploy:sky && npm run reload:sky",
|
"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",
|
"start": "pm2 start dist/app.mjs --name codecenter",
|
||||||
"release": "node ./config/release/index.mjs",
|
"release": "node ./config/release/index.mjs",
|
||||||
"pub": "envision pack -p -u",
|
"pub": "envision pack -p -u",
|
||||||
@ -30,9 +34,7 @@
|
|||||||
"keywords": [],
|
"keywords": [],
|
||||||
"types": "types/index.d.ts",
|
"types": "types/index.d.ts",
|
||||||
"files": [
|
"files": [
|
||||||
"types",
|
"dist"
|
||||||
"dist",
|
|
||||||
"src"
|
|
||||||
],
|
],
|
||||||
"license": "UNLICENSED",
|
"license": "UNLICENSED",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
@ -289,9 +289,19 @@
|
|||||||
|
|
||||||
import { User, UserInit, UserServices } from '@kevisual/code-center-module/models';
|
import { User, UserInit, UserServices } from '@kevisual/code-center-module/models';
|
||||||
export { User, UserInit, UserServices };
|
export { User, UserInit, UserServices };
|
||||||
UserInit(null, null, {
|
import { OrgInit } from '@kevisual/code-center-module/models';
|
||||||
alter: true,
|
const init = async () => {
|
||||||
logging: false,
|
await OrgInit(null, null, {
|
||||||
}).catch((e) => {
|
alter: true,
|
||||||
console.error('User sync', e);
|
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({
|
.route({
|
||||||
path: 'auth',
|
path: 'auth',
|
||||||
id: 'auth',
|
id: 'auth',
|
||||||
|
isDebug: true,
|
||||||
})
|
})
|
||||||
.define(async (ctx) => {
|
.define(async (ctx) => {
|
||||||
const token = ctx.query.token;
|
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 './user-app.ts';
|
||||||
|
|
||||||
import './public/index.ts';
|
import './public/index.ts';
|
||||||
|
import './domain.ts';
|
||||||
|
|
||||||
export * from './module/index.ts';
|
export * from './module/index.ts';
|
||||||
|
@ -140,6 +140,7 @@ app
|
|||||||
path: 'app',
|
path: 'app',
|
||||||
key: 'uploadFiles',
|
key: 'uploadFiles',
|
||||||
middleware: ['auth'],
|
middleware: ['auth'],
|
||||||
|
isDebug: true,
|
||||||
})
|
})
|
||||||
.define(async (ctx) => {
|
.define(async (ctx) => {
|
||||||
try {
|
try {
|
||||||
@ -264,23 +265,6 @@ app
|
|||||||
})
|
})
|
||||||
.addTo(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
|
app
|
||||||
.route({
|
.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 title: string;
|
||||||
declare description: string;
|
declare description: string;
|
||||||
declare version: string;
|
declare version: string;
|
||||||
declare domain: string;
|
|
||||||
declare key: string;
|
declare key: string;
|
||||||
declare uid: string;
|
declare uid: string;
|
||||||
declare pid: string;
|
declare pid: string;
|
||||||
@ -69,10 +68,6 @@ AppModel.init(
|
|||||||
type: DataTypes.STRING,
|
type: DataTypes.STRING,
|
||||||
defaultValue: '',
|
defaultValue: '',
|
||||||
},
|
},
|
||||||
domain: {
|
|
||||||
type: DataTypes.STRING,
|
|
||||||
defaultValue: '',
|
|
||||||
},
|
|
||||||
key: {
|
key: {
|
||||||
type: DataTypes.STRING,
|
type: DataTypes.STRING,
|
||||||
// 和 uid 组合唯一
|
// 和 uid 组合唯一
|
||||||
|
@ -11,3 +11,5 @@ import './file/index.ts';
|
|||||||
import './micro-app/index.ts';
|
import './micro-app/index.ts';
|
||||||
|
|
||||||
import './config/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,
|
id: markModel.id,
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
const [markModel, created] = await MarkModel.findOrCreate({
|
ctx.throw(400, 'id is required');
|
||||||
where: {
|
// const [markModel, created] = await MarkModel.findOrCreate({
|
||||||
uid: tokenUser.id,
|
// where: {
|
||||||
puid: tokenUser.uid,
|
// uid: tokenUser.id,
|
||||||
title: dayjs().format('YYYY-MM-DD'),
|
// puid: tokenUser.uid,
|
||||||
},
|
// title: dayjs().format('YYYY-MM-DD'),
|
||||||
defaults: {
|
// },
|
||||||
title: dayjs().format('YYYY-MM-DD'),
|
// defaults: {
|
||||||
uid: tokenUser.id,
|
// title: dayjs().format('YYYY-MM-DD'),
|
||||||
markType: 'wallnote',
|
// uid: tokenUser.id,
|
||||||
tags: ['daily'],
|
// markType: 'wallnote',
|
||||||
},
|
// tags: ['daily'],
|
||||||
});
|
// },
|
||||||
ctx.body = {
|
// });
|
||||||
version: Number(markModel.version),
|
// ctx.body = {
|
||||||
updatedAt: markModel.updatedAt,
|
// version: Number(markModel.version),
|
||||||
createdAt: markModel.createdAt,
|
// updatedAt: markModel.updatedAt,
|
||||||
id: markModel.id,
|
// createdAt: markModel.createdAt,
|
||||||
created: created,
|
// id: markModel.id,
|
||||||
};
|
// created: created,
|
||||||
|
// };
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.addTo(app);
|
.addTo(app);
|
||||||
@ -87,24 +88,25 @@ app
|
|||||||
}
|
}
|
||||||
ctx.body = markModel;
|
ctx.body = markModel;
|
||||||
} else {
|
} else {
|
||||||
|
ctx.throw(400, 'id is required');
|
||||||
// id 不存在,获取当天的title为 日期的一条数据
|
// id 不存在,获取当天的title为 日期的一条数据
|
||||||
const [markModel, created] = await MarkModel.findOrCreate({
|
// const [markModel, created] = await MarkModel.findOrCreate({
|
||||||
where: {
|
// where: {
|
||||||
uid: tokenUser.id,
|
// uid: tokenUser.id,
|
||||||
puid: tokenUser.uid,
|
// puid: tokenUser.uid,
|
||||||
title: dayjs().format('YYYY-MM-DD'),
|
// title: dayjs().format('YYYY-MM-DD'),
|
||||||
},
|
// },
|
||||||
defaults: {
|
// defaults: {
|
||||||
title: dayjs().format('YYYY-MM-DD'),
|
// title: dayjs().format('YYYY-MM-DD'),
|
||||||
uid: tokenUser.id,
|
// uid: tokenUser.id,
|
||||||
markType: 'wallnote',
|
// markType: 'wallnote',
|
||||||
tags: ['daily'],
|
// tags: ['daily'],
|
||||||
uname: tokenUser.username,
|
// uname: tokenUser.username,
|
||||||
puid: tokenUser.uid,
|
// puid: tokenUser.uid,
|
||||||
version: 1,
|
// version: 1,
|
||||||
},
|
// },
|
||||||
});
|
// });
|
||||||
ctx.body = markModel;
|
// ctx.body = markModel;
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.addTo(app);
|
.addTo(app);
|
||||||
|
@ -12,6 +12,7 @@ export const createCookie = (token: any, ctx: any) => {
|
|||||||
if (!domain) {
|
if (!domain) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
//TODO, 获取访问的 hostname, 如果访问的和 domain 的不一致,也创建cookie
|
||||||
const browser = ctx.req.headers['user-agent'];
|
const browser = ctx.req.headers['user-agent'];
|
||||||
const isBrowser = browser.includes('Mozilla'); // 浏览器
|
const isBrowser = browser.includes('Mozilla'); // 浏览器
|
||||||
if (isBrowser && ctx.res.cookie) {
|
if (isBrowser && ctx.res.cookie) {
|
||||||
@ -50,11 +51,21 @@ export type ReqHeaders = {
|
|||||||
cookie: string; // 饼干
|
cookie: string; // 饼干
|
||||||
};
|
};
|
||||||
export const getSomeInfoFromReq = (ctx: any) => {
|
export const getSomeInfoFromReq = (ctx: any) => {
|
||||||
const headers = ctx.req.headers as ReqHeaders;
|
const headers = ctx.req?.headers as ReqHeaders;
|
||||||
const userAgent = headers['user-agent'];
|
if (!headers) {
|
||||||
const host = headers['host'];
|
console.log('no req headers', ctx.req);
|
||||||
const ip = headers['x-forwarded-for'] || ctx.req.connection.remoteAddress;
|
return {
|
||||||
console.log('req headers', headers);
|
'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 {
|
return {
|
||||||
'user-agent': userAgent,
|
'user-agent': userAgent,
|
||||||
browser: userAgent,
|
browser: userAgent,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user