diff --git a/config.sample.js b/config.sample.js index 4c25830..ff34083 100644 --- a/config.sample.js +++ b/config.sample.js @@ -93,7 +93,7 @@ module.exports = { as any changes in said directory will be detected live. You may even add or remove pages while lolisafe is running. */ - pages: ['home', 'auth', 'dashboard', 'faq'], + pages: ['home', 'auth', 'dashboard', 'faq', 'apidocs'], /* This will load public/libs/cookieconsent/cookieconsent.min.{css,js} on homepage (configured from home.js). diff --git a/controllers/authController.js b/controllers/authController.js index 290d3b8..d0cec9f 100644 --- a/controllers/authController.js +++ b/controllers/authController.js @@ -8,8 +8,8 @@ const utils = require('./utilsController') const ClientError = require('./utils/ClientError') const config = require('./../config') -// Don't forget to update min/max length of text inputs in auth.njk -// when changing these values. +// Don't forget to update min/max length of text inputs in views/auth.njk, +// and OpenAPI spec in routes/api.js when changing these values. const self = { user: { min: 4, diff --git a/controllers/permissionController.js b/controllers/permissionController.js index 65cf417..d72557e 100644 --- a/controllers/permissionController.js +++ b/controllers/permissionController.js @@ -48,7 +48,9 @@ self.higher = (user, target) => { self.mapPermissions = user => { const map = {} Object.keys(self.permissions).forEach(group => { - map[group] = self.is(user, group) + if (self.is(user, group)) { + map[group] = self.is(user, group) + } }) return map } diff --git a/gulpfile.js b/gulpfile.js index 7ce5f5e..754df5a 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -140,9 +140,17 @@ gulp.task('build:js', () => { .pipe(gulp.dest(dist)) }) -gulp.task('build', gulp.parallel('build:sass', 'build:css', 'build:fontello', 'build:js')) +gulp.task('build:openapi-spec', cb => { + exec('node ./scripts/build-openapi-spec.js', (error, stdout, stderr) => { + if (stdout) process.stdout.write(stdout) + if (stderr) process.stderr.write(stderr) + cb(error) + }) +}) -/** TASKS: VERSION STRINGS */ +gulp.task('build', gulp.parallel('build:sass', 'build:css', 'build:fontello', 'build:js', 'build:openapi-spec')) + +/** TASKS: EXEC */ gulp.task('exec:bump-versions', cb => { exec('node ./scripts/bump-versions.js 1', (error, stdout, stderr) => { @@ -192,6 +200,7 @@ gulp.task('nodemon', cb => { watch: [ 'controllers/', 'routes/', + 'scripts/build-openapi-spec.js', 'views/_globals.njk', 'views/_layout.njk', 'views/album.njk', @@ -200,6 +209,7 @@ gulp.task('nodemon', cb => { 'lolisafe.js' ], ext: 'js', + tasks: ['build:openapi-spec'], done: cb }) }) diff --git a/package.json b/package.json index 1ec9e1b..a4aa522 100644 --- a/package.json +++ b/package.json @@ -86,7 +86,8 @@ "postcss": "~8.4.16", "postcss-preset-env": "~7.8.1", "stylelint": "~14.11.0", - "stylelint-config-standard-scss": "~5.0.0" + "stylelint-config-standard-scss": "~5.0.0", + "swagger-jsdoc": "~6.2.5" }, "volta": { "node": "16.17.0", diff --git a/public/libs/swagger-ui/favicon-16x16.png b/public/libs/swagger-ui/favicon-16x16.png new file mode 100644 index 0000000..8b194e6 Binary files /dev/null and b/public/libs/swagger-ui/favicon-16x16.png differ diff --git a/public/libs/swagger-ui/favicon-32x32.png b/public/libs/swagger-ui/favicon-32x32.png new file mode 100644 index 0000000..249737f Binary files /dev/null and b/public/libs/swagger-ui/favicon-32x32.png differ diff --git a/public/libs/swagger-ui/index.css b/public/libs/swagger-ui/index.css new file mode 100644 index 0000000..f2376fd --- /dev/null +++ b/public/libs/swagger-ui/index.css @@ -0,0 +1,16 @@ +html { + box-sizing: border-box; + overflow: -moz-scrollbars-vertical; + overflow-y: scroll; +} + +*, +*:before, +*:after { + box-sizing: inherit; +} + +body { + margin: 0; + background: #fafafa; +} diff --git a/public/libs/swagger-ui/oauth2-redirect.html b/public/libs/swagger-ui/oauth2-redirect.html new file mode 100644 index 0000000..5640917 --- /dev/null +++ b/public/libs/swagger-ui/oauth2-redirect.html @@ -0,0 +1,79 @@ + + +
+>16&255,u[c++]=t>>8&255,u[c++]=255&t;2===s&&(t=n[e.charCodeAt(r)]<<2|n[e.charCodeAt(r+1)]>>4,u[c++]=255&t);1===s&&(t=n[e.charCodeAt(r)]<<10|n[e.charCodeAt(r+1)]<<4|n[e.charCodeAt(r+2)]>>2,u[c++]=t>>8&255,u[c++]=255&t);return u},t.fromByteArray=function(e){for(var t,n=e.length,o=n%3,a=[],i=16383,s=0,l=n-o;s0)throw new Error("Invalid string. Length must be a multiple of 4");var r=e.indexOf("=");return-1===r&&(r=t),[r,r===t?0:4-r%4]}function u(e,t,n){for(var o,a,i=[],s=t;ss&&(r=s-l),a=r;a>=0;a--){let r=!0;for(let n=0;n>>=0,isFinite(r)?(r>>>=0,void 0===n&&(n="utf8")):(n=r,r=void 0)}const o=this.length-t;if((void 0===r||r>o)&&(r=o),e.length>0&&(r<0||t<0)||t>this.length)throw new RangeError("Attempt to write outside buffer bounds");n||(n="utf8");let a=!1;for(;;)switch(n){case"hex":return w(this,e,t,r);case"utf8":case"utf-8":return E(this,e,t,r);case"ascii":case"latin1":case"binary":return x(this,e,t,r);case"base64":return _(this,e,t,r);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return S(this,e,t,r);default:if(a)throw new TypeError("Unknown encoding: "+n);n=(""+n).toLowerCase(),a=!0}},l.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};const C=4096;function O(e,t,r){let n="";r=Math.min(e.length,r);for(let o=t;o