mirror of https://github.com/boxyhq/jackson.git
Store product config
This commit is contained in:
parent
ab46ab1f5e
commit
60cd162672
|
@ -0,0 +1,32 @@
|
|||
import type { NextApiRequest, NextApiResponse } from 'next';
|
||||
|
||||
import jackson from '@lib/jackson';
|
||||
|
||||
const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
try {
|
||||
switch (req.method) {
|
||||
case 'GET':
|
||||
await handleGET(req, res);
|
||||
break;
|
||||
default:
|
||||
res.setHeader('Allow', 'GET');
|
||||
res.status(405).json({ error: { message: `Method ${req.method} Not Allowed` } });
|
||||
}
|
||||
} catch (error: any) {
|
||||
const { message, statusCode = 500 } = error;
|
||||
res.status(statusCode).json({ error: { message } });
|
||||
}
|
||||
};
|
||||
|
||||
// Fetch product configuration
|
||||
const handleGET = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
const { productController } = await jackson();
|
||||
|
||||
const { productId } = req.query as { productId: string };
|
||||
|
||||
const product = await productController.get(productId);
|
||||
|
||||
res.json({ data: product });
|
||||
};
|
||||
|
||||
export default handler;
|
|
@ -0,0 +1,30 @@
|
|||
import type { NextApiRequest, NextApiResponse } from 'next';
|
||||
|
||||
import jackson from '@lib/jackson';
|
||||
|
||||
const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
try {
|
||||
switch (req.method) {
|
||||
case 'POST':
|
||||
await handlePOST(req, res);
|
||||
break;
|
||||
default:
|
||||
res.setHeader('Allow', 'POST');
|
||||
res.status(405).json({ error: { message: `Method ${req.method} Not Allowed` } });
|
||||
}
|
||||
} catch (error: any) {
|
||||
const { message, statusCode = 500 } = error;
|
||||
res.status(statusCode).json({ error: { message } });
|
||||
}
|
||||
};
|
||||
|
||||
// Update product configuration
|
||||
const handlePOST = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
const { productController } = await jackson();
|
||||
|
||||
await productController.upsert(req.body);
|
||||
|
||||
res.end();
|
||||
};
|
||||
|
||||
export default handler;
|
|
@ -19,6 +19,7 @@ const unAuthenticatedApiRoutes = [
|
|||
'/api/setup/**',
|
||||
'/api/branding',
|
||||
'/api/scim/cron/**',
|
||||
// '/api/internals/product/**',
|
||||
];
|
||||
|
||||
export async function middleware(req: NextRequest) {
|
||||
|
@ -44,7 +45,8 @@ export async function middleware(req: NextRequest) {
|
|||
}
|
||||
|
||||
// Validate API routes `/api/v1/**`
|
||||
if (micromatch.isMatch(pathname, '/api/v1/**')) {
|
||||
// Question: Is it okay to use same API key?
|
||||
if (micromatch.isMatch(pathname, ['/api/v1/**', '/api/internals/product/**'])) {
|
||||
if (!validateApiKey(extractAuthToken(req))) {
|
||||
return sendUnAuthorizedResponse({ message: 'Unauthorized' });
|
||||
}
|
||||
|
|
|
@ -1127,7 +1127,7 @@
|
|||
"version": "0.8.1",
|
||||
"resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
|
||||
"integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@jridgewell/trace-mapping": "0.3.9"
|
||||
},
|
||||
|
@ -1320,7 +1320,7 @@
|
|||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz",
|
||||
"integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=6.0.0"
|
||||
}
|
||||
|
@ -1329,13 +1329,13 @@
|
|||
"version": "1.4.15",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
|
||||
"integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==",
|
||||
"devOptional": true
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@jridgewell/trace-mapping": {
|
||||
"version": "0.3.9",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz",
|
||||
"integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@jridgewell/resolve-uri": "^3.0.3",
|
||||
"@jridgewell/sourcemap-codec": "^1.4.10"
|
||||
|
@ -2981,13 +2981,13 @@
|
|||
"version": "1.0.9",
|
||||
"resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz",
|
||||
"integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==",
|
||||
"devOptional": true
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@tsconfig/node12": {
|
||||
"version": "1.0.11",
|
||||
"resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz",
|
||||
"integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==",
|
||||
"devOptional": true
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@tsconfig/node14": {
|
||||
"version": "14.1.0",
|
||||
|
@ -3125,7 +3125,7 @@
|
|||
"version": "8.10.0",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz",
|
||||
"integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"acorn": "bin/acorn"
|
||||
},
|
||||
|
@ -3137,7 +3137,7 @@
|
|||
"version": "8.2.0",
|
||||
"resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz",
|
||||
"integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
|
@ -3252,7 +3252,7 @@
|
|||
"version": "4.1.3",
|
||||
"resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
|
||||
"integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
|
||||
"devOptional": true
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/array-buffer-byte-length": {
|
||||
"version": "1.0.0",
|
||||
|
@ -4040,7 +4040,7 @@
|
|||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
|
||||
"integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
|
||||
"devOptional": true
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/cross-env": {
|
||||
"version": "7.0.3",
|
||||
|
@ -5177,7 +5177,7 @@
|
|||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz",
|
||||
"integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==",
|
||||
"devOptional": true
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/is-actual-promise": {
|
||||
"version": "1.0.1",
|
||||
|
@ -5833,7 +5833,7 @@
|
|||
"version": "1.3.6",
|
||||
"resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
|
||||
"integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
|
||||
"devOptional": true
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/make-fetch-happen": {
|
||||
"version": "13.0.0",
|
||||
|
@ -7221,20 +7221,6 @@
|
|||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-dom": {
|
||||
"version": "18.2.0",
|
||||
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz",
|
||||
"integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==",
|
||||
"dev": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"loose-envify": "^1.1.0",
|
||||
"scheduler": "^0.23.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^18.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-element-to-jsx-string": {
|
||||
"version": "15.0.0",
|
||||
"resolved": "https://registry.npmjs.org/react-element-to-jsx-string/-/react-element-to-jsx-string-15.0.0.tgz",
|
||||
|
@ -7694,7 +7680,7 @@
|
|||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz",
|
||||
"integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 6.0.0",
|
||||
"npm": ">= 3.0.0"
|
||||
|
@ -7704,7 +7690,7 @@
|
|||
"version": "2.7.1",
|
||||
"resolved": "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz",
|
||||
"integrity": "sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ip": "^2.0.0",
|
||||
"smart-buffer": "^4.2.0"
|
||||
|
@ -8291,7 +8277,7 @@
|
|||
"version": "10.9.1",
|
||||
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz",
|
||||
"integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@cspotcode/source-map-support": "^0.8.0",
|
||||
"@tsconfig/node10": "^1.0.7",
|
||||
|
@ -8334,19 +8320,19 @@
|
|||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz",
|
||||
"integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==",
|
||||
"devOptional": true
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/ts-node/node_modules/@tsconfig/node16": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz",
|
||||
"integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==",
|
||||
"devOptional": true
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/ts-node/node_modules/diff": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
|
||||
"integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.3.1"
|
||||
}
|
||||
|
@ -8682,7 +8668,7 @@
|
|||
"version": "5.2.2",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz",
|
||||
"integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
"tsserver": "bin/tsserver"
|
||||
|
@ -8765,7 +8751,7 @@
|
|||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
|
||||
"integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==",
|
||||
"devOptional": true
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/v8-to-istanbul": {
|
||||
"version": "9.1.3",
|
||||
|
@ -9219,7 +9205,7 @@
|
|||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
|
||||
"integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
import { throwIfInvalidLicense } from '../common/checkLicense';
|
||||
import type { Storable, Product, JacksonOption } from '../../typings';
|
||||
|
||||
export class ProductController {
|
||||
private productStore: Storable;
|
||||
private opts: JacksonOption;
|
||||
|
||||
constructor({ productStore, opts }: { productStore: Storable; opts: JacksonOption }) {
|
||||
this.productStore = productStore;
|
||||
this.opts = opts;
|
||||
}
|
||||
|
||||
public async get(productId: string) {
|
||||
await throwIfInvalidLicense(this.opts.boxyhqLicenseKey);
|
||||
|
||||
return (await this.productStore.get(productId)) as Product;
|
||||
}
|
||||
|
||||
public async upsert(product: Product) {
|
||||
await throwIfInvalidLicense(this.opts.boxyhqLicenseKey);
|
||||
|
||||
await this.productStore.put(product.id, { ...product });
|
||||
}
|
||||
}
|
|
@ -18,6 +18,7 @@ import checkLicense from './ee/common/checkLicense';
|
|||
import { BrandingController } from './ee/branding';
|
||||
import SAMLTracer from './saml-tracer';
|
||||
import EventController from './event';
|
||||
import { ProductController } from './ee/product';
|
||||
|
||||
const defaultOpts = (opts: JacksonOption): JacksonOption => {
|
||||
const newOpts = {
|
||||
|
@ -69,6 +70,7 @@ export const controllers = async (
|
|||
samlFederatedController: ISAMLFederationController;
|
||||
brandingController: IBrandingController;
|
||||
checkLicense: () => Promise<boolean>;
|
||||
productController: ProductController;
|
||||
}> => {
|
||||
opts = defaultOpts(opts);
|
||||
|
||||
|
@ -82,6 +84,7 @@ export const controllers = async (
|
|||
const setupLinkStore = db.store('setup:link');
|
||||
const certificateStore = db.store('x509:certificates');
|
||||
const settingsStore = db.store('portal:settings');
|
||||
const productStore = db.store('product:config');
|
||||
|
||||
const samlTracer = new SAMLTracer({ db });
|
||||
const eventController = new EventController({ opts });
|
||||
|
@ -91,6 +94,7 @@ export const controllers = async (
|
|||
const healthCheckController = new HealthCheckController({ healthCheckStore });
|
||||
await healthCheckController.init();
|
||||
const setupLinkController = new SetupLinkController({ setupLinkStore });
|
||||
const productController = new ProductController({ productStore, opts });
|
||||
|
||||
if (!opts.noAnalytics) {
|
||||
console.info(
|
||||
|
@ -163,6 +167,7 @@ export const controllers = async (
|
|||
checkLicense: () => {
|
||||
return checkLicense(opts.boxyhqLicenseKey);
|
||||
},
|
||||
productController,
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -575,3 +575,10 @@ export type GetByProductParams = {
|
|||
};
|
||||
|
||||
export type SortOrder = 'ASC' | 'DESC';
|
||||
|
||||
export type Product = {
|
||||
id: string;
|
||||
name: string;
|
||||
teamId: string;
|
||||
teamName: string;
|
||||
};
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1 @@
|
|||
export { default } from 'ee/product/api/[productId]';
|
|
@ -0,0 +1 @@
|
|||
export { default } from '@ee/product/api/index';
|
Loading…
Reference in New Issue