@cored3v/web-core 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/app/createApp.d.ts +6 -0
- package/dist/app/createApp.js +91 -0
- package/dist/app/security.d.ts +2 -0
- package/dist/app/security.js +12 -0
- package/dist/auth/jwt.d.ts +4 -0
- package/dist/auth/jwt.js +27 -0
- package/dist/config/index.d.ts +2 -0
- package/dist/config/index.js +13 -0
- package/dist/db/index.d.ts +15 -0
- package/dist/db/index.js +14 -0
- package/dist/db/postgres.d.ts +12 -0
- package/dist/db/postgres.js +12 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +20 -0
- package/dist/license/crypto.d.ts +1 -0
- package/dist/license/crypto.js +18 -0
- package/dist/license/types.d.ts +7 -0
- package/dist/license/types.js +2 -0
- package/dist/license/verify.d.ts +4 -0
- package/dist/license/verify.js +24 -0
- package/dist/types.d.ts +28 -0
- package/dist/types.js +2 -0
- package/package.json +29 -0
package/README.md
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
This is a package to protect source code against unauthorised use
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.createApp = createApp;
|
|
40
|
+
const express_1 = __importStar(require("express"));
|
|
41
|
+
const http_1 = __importDefault(require("http"));
|
|
42
|
+
const config_1 = require("../config");
|
|
43
|
+
const verify_1 = require("../license/verify");
|
|
44
|
+
const security_1 = require("./security");
|
|
45
|
+
const db_1 = require("../db");
|
|
46
|
+
const jwt_1 = require("../auth/jwt");
|
|
47
|
+
async function createApp(opts) {
|
|
48
|
+
// 1) CONFIG
|
|
49
|
+
const config = (0, config_1.loadConfig)();
|
|
50
|
+
// 2) LICENSE GATE
|
|
51
|
+
await (0, verify_1.verifyLicense)({
|
|
52
|
+
appId: opts.appId,
|
|
53
|
+
licensePath: config.get("LICENSE_PATH", "./license.json"),
|
|
54
|
+
});
|
|
55
|
+
// 3) EXPRESS INIT
|
|
56
|
+
const app = (0, express_1.default)();
|
|
57
|
+
const server = http_1.default.createServer(app);
|
|
58
|
+
const router = (0, express_1.Router)();
|
|
59
|
+
if (opts.http?.trustProxy)
|
|
60
|
+
app.set("trust proxy", true);
|
|
61
|
+
// 4) CORE MIDDLEWARE
|
|
62
|
+
(0, security_1.applySecurity)(app);
|
|
63
|
+
app.use(express_1.default.json());
|
|
64
|
+
app.use(express_1.default.urlencoded({ extended: false }));
|
|
65
|
+
// 5) DB (non-optional if declared)
|
|
66
|
+
const db = await (0, db_1.initDb)(opts.db);
|
|
67
|
+
// 6) AUTH
|
|
68
|
+
const auth = (0, jwt_1.initJwtAuth)(config);
|
|
69
|
+
// 7) ROUTES
|
|
70
|
+
if (opts.routes) {
|
|
71
|
+
opts.routes({ app, router, db, auth, config });
|
|
72
|
+
}
|
|
73
|
+
app.use(router);
|
|
74
|
+
// 8) ERROR HANDLER
|
|
75
|
+
app.use((err, _req, res, _next) => {
|
|
76
|
+
console.error(err);
|
|
77
|
+
res.status(500).json({ error: "Internal Server Error from web-core" });
|
|
78
|
+
});
|
|
79
|
+
// 9) LIFE CYCLE
|
|
80
|
+
async function start() {
|
|
81
|
+
const port = opts.http?.port ?? config.get("PORT", 3000);
|
|
82
|
+
await new Promise((resolve) => server.listen(port, resolve));
|
|
83
|
+
console.log(`[web-core] listening on ${port}`);
|
|
84
|
+
}
|
|
85
|
+
async function shutdown() {
|
|
86
|
+
if (db?.close)
|
|
87
|
+
await db.close();
|
|
88
|
+
server.close();
|
|
89
|
+
}
|
|
90
|
+
return { app, start, shutdown };
|
|
91
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.applySecurity = applySecurity;
|
|
7
|
+
const helmet_1 = __importDefault(require("helmet"));
|
|
8
|
+
const cors_1 = __importDefault(require("cors"));
|
|
9
|
+
function applySecurity(app) {
|
|
10
|
+
app.use((0, helmet_1.default)());
|
|
11
|
+
app.use((0, cors_1.default)());
|
|
12
|
+
}
|
package/dist/auth/jwt.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.initJwtAuth = initJwtAuth;
|
|
7
|
+
const jsonwebtoken_1 = __importDefault(require("jsonwebtoken"));
|
|
8
|
+
function initJwtAuth(config) {
|
|
9
|
+
const secret = config.get("JWT_SECRET");
|
|
10
|
+
if (!secret)
|
|
11
|
+
throw new Error("JWT_SECRET missing");
|
|
12
|
+
return {
|
|
13
|
+
middleware() {
|
|
14
|
+
return (req, _res, next) => {
|
|
15
|
+
const h = req.headers.authorization;
|
|
16
|
+
if (!h)
|
|
17
|
+
return next();
|
|
18
|
+
try {
|
|
19
|
+
const token = h.replace("Bearer ", "");
|
|
20
|
+
req.user = jsonwebtoken_1.default.verify(token, secret);
|
|
21
|
+
}
|
|
22
|
+
catch { }
|
|
23
|
+
next();
|
|
24
|
+
};
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.loadConfig = loadConfig;
|
|
4
|
+
function loadConfig() {
|
|
5
|
+
return {
|
|
6
|
+
get(key, fallback) {
|
|
7
|
+
const val = process.env[key];
|
|
8
|
+
if (val === undefined)
|
|
9
|
+
return fallback;
|
|
10
|
+
return val;
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export declare function initDb(opts?: {
|
|
2
|
+
type: "postgres";
|
|
3
|
+
uri?: string;
|
|
4
|
+
}): Promise<{
|
|
5
|
+
query: {
|
|
6
|
+
<T extends import("pg").Submittable>(queryStream: T): T;
|
|
7
|
+
<R extends any[] = any[], I = any[]>(queryConfig: import("pg").QueryArrayConfig<I>, values?: import("pg").QueryConfigValues<I>): Promise<import("pg").QueryArrayResult<R>>;
|
|
8
|
+
<R extends import("pg").QueryResultRow = any, I = any>(queryConfig: import("pg").QueryConfig<I>): Promise<import("pg").QueryResult<R>>;
|
|
9
|
+
<R extends import("pg").QueryResultRow = any, I = any[]>(queryTextOrConfig: string | import("pg").QueryConfig<I>, values?: import("pg").QueryConfigValues<I>): Promise<import("pg").QueryResult<R>>;
|
|
10
|
+
<R extends any[] = any[], I = any[]>(queryConfig: import("pg").QueryArrayConfig<I>, callback: (err: Error, result: import("pg").QueryArrayResult<R>) => void): void;
|
|
11
|
+
<R extends import("pg").QueryResultRow = any, I = any[]>(queryTextOrConfig: string | import("pg").QueryConfig<I>, callback: (err: Error, result: import("pg").QueryResult<R>) => void): void;
|
|
12
|
+
<R extends import("pg").QueryResultRow = any, I = any[]>(queryText: string, values: import("pg").QueryConfigValues<I>, callback: (err: Error, result: import("pg").QueryResult<R>) => void): void;
|
|
13
|
+
};
|
|
14
|
+
close: () => Promise<void>;
|
|
15
|
+
} | null>;
|
package/dist/db/index.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.initDb = initDb;
|
|
4
|
+
const postgres_1 = require("./postgres");
|
|
5
|
+
async function initDb(opts) {
|
|
6
|
+
if (!opts)
|
|
7
|
+
return null;
|
|
8
|
+
if (opts.type === "postgres") {
|
|
9
|
+
if (!opts.uri)
|
|
10
|
+
throw new Error("Postgres URI required");
|
|
11
|
+
return (0, postgres_1.initPostgres)(opts.uri);
|
|
12
|
+
}
|
|
13
|
+
throw new Error("Unsupported DB");
|
|
14
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare function initPostgres(uri: string): Promise<{
|
|
2
|
+
query: {
|
|
3
|
+
<T extends import("pg").Submittable>(queryStream: T): T;
|
|
4
|
+
<R extends any[] = any[], I = any[]>(queryConfig: import("pg").QueryArrayConfig<I>, values?: import("pg").QueryConfigValues<I>): Promise<import("pg").QueryArrayResult<R>>;
|
|
5
|
+
<R extends import("pg").QueryResultRow = any, I = any>(queryConfig: import("pg").QueryConfig<I>): Promise<import("pg").QueryResult<R>>;
|
|
6
|
+
<R extends import("pg").QueryResultRow = any, I = any[]>(queryTextOrConfig: string | import("pg").QueryConfig<I>, values?: import("pg").QueryConfigValues<I>): Promise<import("pg").QueryResult<R>>;
|
|
7
|
+
<R extends any[] = any[], I = any[]>(queryConfig: import("pg").QueryArrayConfig<I>, callback: (err: Error, result: import("pg").QueryArrayResult<R>) => void): void;
|
|
8
|
+
<R extends import("pg").QueryResultRow = any, I = any[]>(queryTextOrConfig: string | import("pg").QueryConfig<I>, callback: (err: Error, result: import("pg").QueryResult<R>) => void): void;
|
|
9
|
+
<R extends import("pg").QueryResultRow = any, I = any[]>(queryText: string, values: import("pg").QueryConfigValues<I>, callback: (err: Error, result: import("pg").QueryResult<R>) => void): void;
|
|
10
|
+
};
|
|
11
|
+
close: () => Promise<void>;
|
|
12
|
+
}>;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.initPostgres = initPostgres;
|
|
4
|
+
const pg_1 = require("pg");
|
|
5
|
+
async function initPostgres(uri) {
|
|
6
|
+
const client = new pg_1.Client({ connectionString: uri });
|
|
7
|
+
await client.connect();
|
|
8
|
+
return {
|
|
9
|
+
query: client.query.bind(client),
|
|
10
|
+
close: () => client.end(),
|
|
11
|
+
};
|
|
12
|
+
}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.createApp = void 0;
|
|
18
|
+
var createApp_1 = require("./app/createApp");
|
|
19
|
+
Object.defineProperty(exports, "createApp", { enumerable: true, get: function () { return createApp_1.createApp; } });
|
|
20
|
+
__exportStar(require("./types"), exports);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function verifySignature(payload: object, signature: string): boolean;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.verifySignature = verifySignature;
|
|
7
|
+
const crypto_1 = __importDefault(require("crypto"));
|
|
8
|
+
const PUBLIC_KEY = `
|
|
9
|
+
-----BEGIN PUBLIC KEY-----
|
|
10
|
+
REPLACE WITH YOUR RSA PUBLIC KEY
|
|
11
|
+
-----END PUBLIC KEY-----
|
|
12
|
+
`;
|
|
13
|
+
function verifySignature(payload, signature) {
|
|
14
|
+
const verify = crypto_1.default.createVerify("RSA-SHA256");
|
|
15
|
+
verify.update(JSON.stringify(payload));
|
|
16
|
+
verify.end();
|
|
17
|
+
return verify.verify(PUBLIC_KEY, Buffer.from(signature, "base64"));
|
|
18
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.verifyLicense = verifyLicense;
|
|
7
|
+
const fs_1 = __importDefault(require("fs"));
|
|
8
|
+
const crypto_1 = require("./crypto");
|
|
9
|
+
async function verifyLicense(opts) {
|
|
10
|
+
if (!fs_1.default.existsSync(opts.licensePath)) {
|
|
11
|
+
throw new Error("License file not found");
|
|
12
|
+
}
|
|
13
|
+
const raw = JSON.parse(fs_1.default.readFileSync(opts.licensePath, "utf8"));
|
|
14
|
+
const { signature, ...payload } = raw;
|
|
15
|
+
if (raw.appId !== opts.appId) {
|
|
16
|
+
throw new Error("License appId mismatch");
|
|
17
|
+
}
|
|
18
|
+
if (new Date(raw.expiresAt) < new Date()) {
|
|
19
|
+
throw new Error("License expired");
|
|
20
|
+
}
|
|
21
|
+
if (!(0, crypto_1.verifySignature)(payload, signature)) {
|
|
22
|
+
throw new Error("Invalid license signature");
|
|
23
|
+
}
|
|
24
|
+
}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Express, Router } from "express";
|
|
2
|
+
export interface CreateAppOptions {
|
|
3
|
+
appId: string;
|
|
4
|
+
http?: {
|
|
5
|
+
port?: number;
|
|
6
|
+
trustProxy?: boolean;
|
|
7
|
+
};
|
|
8
|
+
db?: {
|
|
9
|
+
type: "postgres";
|
|
10
|
+
uri?: string;
|
|
11
|
+
};
|
|
12
|
+
auth?: {
|
|
13
|
+
provider: "jwt";
|
|
14
|
+
};
|
|
15
|
+
routes?: (ctx: AppContext) => void;
|
|
16
|
+
}
|
|
17
|
+
export interface AppContext {
|
|
18
|
+
app: Express;
|
|
19
|
+
router: Router;
|
|
20
|
+
db: any;
|
|
21
|
+
auth: {
|
|
22
|
+
middleware(): any;
|
|
23
|
+
};
|
|
24
|
+
config: Config;
|
|
25
|
+
}
|
|
26
|
+
export interface Config {
|
|
27
|
+
get<T = any>(key: string, fallback?: T): T;
|
|
28
|
+
}
|
package/dist/types.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@cored3v/web-core",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Reusable licensed Express core for web applications",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist"
|
|
9
|
+
],
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsc",
|
|
12
|
+
"prepublishOnly": "npm run build"
|
|
13
|
+
},
|
|
14
|
+
"dependencies": {
|
|
15
|
+
"cors": "^2.8.5",
|
|
16
|
+
"express": "^4.19.2",
|
|
17
|
+
"helmet": "^7.1.0",
|
|
18
|
+
"jsonwebtoken": "^9.0.2",
|
|
19
|
+
"pg": "^8.11.5"
|
|
20
|
+
},
|
|
21
|
+
"devDependencies": {
|
|
22
|
+
"@types/cors": "^2.8.19",
|
|
23
|
+
"@types/express": "^4.17.21",
|
|
24
|
+
"@types/jsonwebtoken": "^9.0.6",
|
|
25
|
+
"@types/node": "^20.11.0",
|
|
26
|
+
"@types/pg": "^8.16.0",
|
|
27
|
+
"typescript": "^5.4.0"
|
|
28
|
+
}
|
|
29
|
+
}
|