nitro-web 0.0.98 → 0.0.100
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/package.json +3 -2
- package/server/index.js +5 -0
- package/server/router.js +50 -23
- package/types/server/index.d.ts +4 -0
- package/types/server/index.d.ts.map +1 -1
- package/types/server/router.d.ts +18 -12
- package/types/server/router.d.ts.map +1 -1
- package/types.ts +2 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nitro-web",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.100",
|
|
4
4
|
"repository": "github:boycce/nitro-web",
|
|
5
5
|
"homepage": "https://boycce.github.io/nitro-web/",
|
|
6
6
|
"description": "Nitro is a battle-tested, modular base project to turbocharge your projects, styled using Tailwind 🚀",
|
|
@@ -55,7 +55,8 @@
|
|
|
55
55
|
"tailwind-merge": "^2.6.0"
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
|
58
|
-
"@types/dateformat": "^5.0.3"
|
|
58
|
+
"@types/dateformat": "^5.0.3",
|
|
59
|
+
"@typescript-eslint/eslint-plugin": "^8.18.1"
|
|
59
60
|
},
|
|
60
61
|
"peerDependencies": {
|
|
61
62
|
"@stripe/stripe-js": "^1.34.0",
|
package/server/index.js
CHANGED
|
@@ -2,6 +2,11 @@
|
|
|
2
2
|
export * from '../util.js'
|
|
3
3
|
export * as util from '../util.js'
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* Re-export the MiddlewareConfig type from nitro-web/server
|
|
7
|
+
* @typedef {import('./router.js').MiddlewareConfig} MiddlewareConfig
|
|
8
|
+
*/
|
|
9
|
+
|
|
5
10
|
// Export models
|
|
6
11
|
import userModel from './models/user.js'
|
|
7
12
|
import companyModel from './models/company.js'
|
package/server/router.js
CHANGED
|
@@ -12,9 +12,29 @@ import sortRouteAddressesNodeps from 'sort-route-addresses-nodeps'
|
|
|
12
12
|
import { sendEmail } from 'nitro-web/server'
|
|
13
13
|
import * as util from 'nitro-web/util'
|
|
14
14
|
|
|
15
|
+
/**
|
|
16
|
+
* @typedef {express.Request & {
|
|
17
|
+
* version: string,
|
|
18
|
+
* user?: import('types').User,
|
|
19
|
+
* }} Request
|
|
20
|
+
* @typedef {express.Response & {
|
|
21
|
+
* error: (msg?: string | Error | Error[], detail?: string) => void,
|
|
22
|
+
* unauthorized: (msg?: string | Error | Error[]) => void,
|
|
23
|
+
* forbidden: (msg?: string | Error | Error[]) => void,
|
|
24
|
+
* notFound: (msg?: string | Error | Error[]) => void,
|
|
25
|
+
* serverError: (msg?: string | Error | Error[]) => void,
|
|
26
|
+
* }} Response
|
|
27
|
+
* @typedef {{
|
|
28
|
+
* order: string[],
|
|
29
|
+
* [key: string]: ((req: Request, res: Response, next: Function) => void) | string[],
|
|
30
|
+
* }} MiddlewareConfig
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
let configLocal
|
|
15
34
|
const _dirname = dirname(fileURLToPath(import.meta.url)) + '/'
|
|
16
35
|
|
|
17
36
|
export async function setupRouter (config) {
|
|
37
|
+
configLocal = config
|
|
18
38
|
const { env, middleware: configMiddleware, version } = config
|
|
19
39
|
const { componentsDir, distDir, emailTemplateDir } = util.getDirectories(path, config.pwd)
|
|
20
40
|
const expressApp = express()
|
|
@@ -53,8 +73,9 @@ export async function setupRouter (config) {
|
|
|
53
73
|
|
|
54
74
|
if (routes?.setup) routes.setup.call(routes, allMiddleware, config)
|
|
55
75
|
if (routes) {
|
|
56
|
-
util.each(routes, (_middleware,
|
|
57
|
-
if (!
|
|
76
|
+
util.each(routes, (_middleware, _key) => {
|
|
77
|
+
if (!_key.match(/\s/)) return
|
|
78
|
+
const key = _key.replace(/\s+/g, ' ')
|
|
58
79
|
const match = key.match(new RegExp(`^(${verbs.join('|')})\\s+(.*)$`, 'i'))
|
|
59
80
|
if (!match) throw new Error(`Invalid verb or path: ${key}`)
|
|
60
81
|
apiRoutes[key] = {
|
|
@@ -297,6 +318,7 @@ function resolveMiddleware (controllers, middleware, route, item) {
|
|
|
297
318
|
}
|
|
298
319
|
}
|
|
299
320
|
|
|
321
|
+
/** @type {MiddlewareConfig} */
|
|
300
322
|
export const middleware = {
|
|
301
323
|
// Default middleware called before all /api/* routes
|
|
302
324
|
order: [
|
|
@@ -350,39 +372,44 @@ export const middleware = {
|
|
|
350
372
|
|
|
351
373
|
// --- Custom middleware ----------------------
|
|
352
374
|
|
|
375
|
+
|
|
353
376
|
isAdmin: (req, res, next) => {
|
|
354
377
|
// Still need to remove cookie matching in favour of uid..
|
|
355
378
|
// E.g. Cookie matching handy for rare issues, e.g. signout > signin (to a different user on another tab)
|
|
356
379
|
const user = req.user
|
|
357
|
-
let cookieMatch = user && (!req.headers.authid || user._id
|
|
358
|
-
if (cookieMatch && (user.type?.match(/admin/) || user.isAdmin)) next()
|
|
380
|
+
let cookieMatch = user && (!req.headers.authid || user._id?.toString() == req.headers.authid)
|
|
381
|
+
if (cookieMatch && user && (user.type?.match(/admin/) || user.isAdmin)) next()
|
|
359
382
|
else if (user && (user.type?.match(/admin/) || user.isAdmin)) res.unauthorized('Invalid cookie, please refresh your browser')
|
|
360
383
|
else if (user) res.unauthorized('You are not authorised to make this request.')
|
|
361
384
|
else res.unauthorized('Please sign in first.')
|
|
362
385
|
},
|
|
363
|
-
isCompanyOwner: (req, res, next) => {
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
},
|
|
373
|
-
isCompanyUser: (req, res, next) => {
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
},
|
|
386
|
+
// isCompanyOwner: (req, res, next) => {
|
|
387
|
+
// let user = req.user || { companies: [] }
|
|
388
|
+
// let cid = req.params.cid
|
|
389
|
+
// let company = user.companies.find((o) => o._id.toString() == cid)
|
|
390
|
+
// let companyUser = company?.users?.find((o) => o._id.toString() == user._id?.toString())
|
|
391
|
+
// if (!user._id) return res.unauthorized('Please sign in first.')
|
|
392
|
+
// else if (!company || !companyUser) res.unauthorized('You are not authorised to make this request.')
|
|
393
|
+
// else if (companyUser.type != 'owner') res.unauthorized('Only owners can make this request.')
|
|
394
|
+
// else next()
|
|
395
|
+
// },
|
|
396
|
+
// isCompanyUser: (req, res, next) => {
|
|
397
|
+
// let user = req.user || { companies: [] }
|
|
398
|
+
// let cid = req.params.cid
|
|
399
|
+
// let company = user.companies.find((o) => o._id.toString() == cid)
|
|
400
|
+
// if (!user._id) return res.unauthorized('Please sign in first.')
|
|
401
|
+
// else if (!company) res.unauthorized('You are not authorised to make this request.')
|
|
402
|
+
// else next()
|
|
403
|
+
// },
|
|
381
404
|
isUser: (req, res, next) => {
|
|
382
405
|
// todo: need to double check that uid is always defined
|
|
383
406
|
let uid = req.params.uid
|
|
384
|
-
if (req.user && (typeof uid == 'undefined' || req.user._id
|
|
407
|
+
if (req.user && (typeof uid == 'undefined' || req.user._id?.toString() == uid)) next()
|
|
385
408
|
else if (req.user) res.unauthorized('You are not authorised to make this request.')
|
|
386
409
|
else res.unauthorized('Please sign in first.')
|
|
387
410
|
},
|
|
411
|
+
isDevelopment: (req, res, next) => {
|
|
412
|
+
if (configLocal.env !== 'development') res.error('This API endpoint is only available in development')
|
|
413
|
+
else next()
|
|
414
|
+
},
|
|
388
415
|
}
|
package/types/server/index.d.ts
CHANGED
|
@@ -5,6 +5,10 @@ export * as util from "../util.js";
|
|
|
5
5
|
export { sendEmail } from "./email/index.js";
|
|
6
6
|
export { routes as authRoutes } from "../components/auth/auth.api.js";
|
|
7
7
|
export { routes as stripeRoutes } from "../components/billing/stripe.api.js";
|
|
8
|
+
/**
|
|
9
|
+
* Re-export the MiddlewareConfig type from nitro-web/server
|
|
10
|
+
*/
|
|
11
|
+
export type MiddlewareConfig = import("./router.js").MiddlewareConfig;
|
|
8
12
|
import userModel from './models/user.js';
|
|
9
13
|
import companyModel from './models/company.js';
|
|
10
14
|
export function setupDefaultModels(db: any): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../server/index.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../server/index.js"],"names":[],"mappings":";;;;;;;;;;+BAMa,OAAO,aAAa,EAAE,gBAAgB;sBAI7B,kBAAkB;yBACf,qBAAqB;AAC9C,2DAIC"}
|
package/types/server/router.d.ts
CHANGED
|
@@ -1,15 +1,21 @@
|
|
|
1
1
|
export function setupRouter(config: any): Promise<http.Server<typeof http.IncomingMessage, typeof http.ServerResponse>>;
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
2
|
+
/** @type {MiddlewareConfig} */
|
|
3
|
+
export const middleware: MiddlewareConfig;
|
|
4
|
+
export type Request = express.Request & {
|
|
5
|
+
version: string;
|
|
6
|
+
user?: any;
|
|
7
|
+
};
|
|
8
|
+
export type Response = express.Response & {
|
|
9
|
+
error: (msg?: string | Error | Error[], detail?: string) => void;
|
|
10
|
+
unauthorized: (msg?: string | Error | Error[]) => void;
|
|
11
|
+
forbidden: (msg?: string | Error | Error[]) => void;
|
|
12
|
+
notFound: (msg?: string | Error | Error[]) => void;
|
|
13
|
+
serverError: (msg?: string | Error | Error[]) => void;
|
|
14
|
+
};
|
|
15
|
+
export type MiddlewareConfig = {
|
|
16
|
+
order: string[];
|
|
17
|
+
[key: string]: ((req: Request, res: Response, next: Function) => void) | string[];
|
|
18
|
+
};
|
|
14
19
|
import http from 'http';
|
|
20
|
+
import express from 'express';
|
|
15
21
|
//# sourceMappingURL=router.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../server/router.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../server/router.js"],"names":[],"mappings":"AAmCA,wHA6HC;AAgKD,+BAA+B;AAC/B,yBADW,gBAAgB,CA8F1B;sBA/YY,OAAO,CAAC,OAAO,GAAG;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,GAAoB,CAAC;CAC7B;uBACS,OAAO,CAAC,QAAQ,GAAG;IAC3B,KAAK,EAAE,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,KAAK,EAAE,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACjE,YAAY,EAAE,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,KAAK,EAAE,KAAK,IAAI,CAAC;IACvD,SAAS,EAAE,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,KAAK,EAAE,KAAK,IAAI,CAAC;IACpD,QAAQ,EAAE,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,KAAK,EAAE,KAAK,IAAI,CAAC;IACnD,WAAW,EAAE,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,KAAK,EAAE,KAAK,IAAI,CAAC;CACvD;+BACS;IACR,KAAK,EAAE,MAAM,EAAE,CAAC;IACpB,CAAK,GAAG,EAAE,MAAM,GAAG,CAAC,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,UAAU,KAAK,IAAI,CAAC,GAAG,MAAM,EAAE,CAAC;CACnF;iBA1Ba,MAAM;oBAIH,SAAS"}
|