DataInventory
Changes
.editorconfig 13(+13 -0)
.env.example 18(+18 -0)
.gitignore 16(+16 -0)
ace 21(+21 -0)
app/Middleware/ConvertEmptyStringsToNull.js 17(+17 -0)
app/Models/Token.js 9(+9 -0)
app/Models/Traits/NoTimestamp.js 16(+16 -0)
app/Models/User.js 39(+39 -0)
config/app.js 243(+243 -0)
config/auth.js 94(+94 -0)
config/bodyParser.js 157(+157 -0)
config/cors.js 87(+87 -0)
config/database.js 81(+81 -0)
config/hash.js 49(+49 -0)
config/session.js 101(+101 -0)
config/shield.js 145(+145 -0)
database/factory.js 21(+21 -0)
database/migrations/1503248427885_user.js 22(+22 -0)
database/migrations/1503248427886_token.js 23(+23 -0)
package.json 35(+35 -0)
public/css/main.css 1(+1 -0)
public/logo.svg 1(+1 -0)
public/pyramid.png 0(+0 -0)
public/splash.png 0(+0 -0)
public/style.css 92(+92 -0)
public/title.svg 1(+1 -0)
README.md 31(+31 -0)
resources/views/inc/footer.edge 1(+1 -0)
resources/views/inc/nav.edge 6(+6 -0)
resources/views/index.edge 7(+7 -0)
resources/views/layouts/main.edge 31(+31 -0)
resources/views/welcome.edge 20(+20 -0)
server.js 25(+25 -0)
start/app.js 61(+61 -0)
start/kernel.js 63(+63 -0)
start/routes.js 20(+20 -0)
Details
.editorconfig 13(+13 -0)
diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..9142239
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,13 @@
+# editorconfig.org
+root = true
+
+[*]
+indent_size = 2
+indent_style = space
+end_of_line = lf
+charset = utf-8
+trim_trailing_whitespace = true
+insert_final_newline = true
+
+[*.md]
+trim_trailing_whitespace = false
.env.example 18(+18 -0)
diff --git a/.env.example b/.env.example
new file mode 100644
index 0000000..6a2fb47
--- /dev/null
+++ b/.env.example
@@ -0,0 +1,18 @@
+HOST=127.0.0.1
+PORT=3333
+NODE_ENV=development
+APP_URL=http://${HOST}:${PORT}
+
+CACHE_VIEWS=false
+
+APP_KEY=
+
+DB_CONNECTION=sqlite
+DB_HOST=127.0.0.1
+DB_PORT=3306
+DB_USER=root
+DB_PASSWORD=
+DB_DATABASE=adonis
+
+SESSION_DRIVER=cookie
+HASH_DRIVER=bcrypt
.gitignore 16(+16 -0)
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..585b363
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,16 @@
+# Node modules
+node_modules
+package-lock.json
+
+# Adonis directory for storing tmp files
+tmp
+
+# Environment variables, never commit this file
+.env
+
+# The development sqlite file
+database/*.sqlite
+
+# VSCode & Webstorm history directories
+.history
+.idea
ace 21(+21 -0)
diff --git a/ace b/ace
new file mode 100644
index 0000000..271a604
--- /dev/null
+++ b/ace
@@ -0,0 +1,21 @@
+'use strict'
+
+/*
+|--------------------------------------------------------------------------
+| Ace Commands
+|--------------------------------------------------------------------------
+|
+| The ace file is just a regular Javascript file but with no extension. You
+| can call `node ace` followed by the command name and it just works.
+|
+| Also you can use `adonis` followed by the command name, since the adonis
+| global proxy all the ace commands.
+|
+*/
+
+const { Ignitor } = require('@adonisjs/ignitor')
+
+new Ignitor(require('@adonisjs/fold'))
+ .appRoot(__dirname)
+ .fireAce()
+ .catch(console.error)
app/Middleware/ConvertEmptyStringsToNull.js 17(+17 -0)
diff --git a/app/Middleware/ConvertEmptyStringsToNull.js b/app/Middleware/ConvertEmptyStringsToNull.js
new file mode 100644
index 0000000..a5750cc
--- /dev/null
+++ b/app/Middleware/ConvertEmptyStringsToNull.js
@@ -0,0 +1,17 @@
+'use strict'
+
+class ConvertEmptyStringsToNull {
+ async handle ({ request }, next) {
+ if (Object.keys(request.body).length) {
+ request.body = Object.assign(
+ ...Object.keys(request.body).map(key => ({
+ [key]: request.body[key] !== '' ? request.body[key] : null
+ }))
+ )
+ }
+
+ await next()
+ }
+}
+
+module.exports = ConvertEmptyStringsToNull
app/Models/Token.js 9(+9 -0)
diff --git a/app/Models/Token.js b/app/Models/Token.js
new file mode 100644
index 0000000..e089e87
--- /dev/null
+++ b/app/Models/Token.js
@@ -0,0 +1,9 @@
+'use strict'
+
+/** @type {typeof import('@adonisjs/lucid/src/Lucid/Model')} */
+const Model = use('Model')
+
+class Token extends Model {
+}
+
+module.exports = Token
app/Models/Traits/NoTimestamp.js 16(+16 -0)
diff --git a/app/Models/Traits/NoTimestamp.js b/app/Models/Traits/NoTimestamp.js
new file mode 100644
index 0000000..58c9340
--- /dev/null
+++ b/app/Models/Traits/NoTimestamp.js
@@ -0,0 +1,16 @@
+'use strict'
+
+class NoTimestamp {
+ register (Model) {
+ Object.defineProperties(Model, {
+ createdAtColumn: {
+ get: () => null,
+ },
+ updatedAtColumn: {
+ get: () => null,
+ },
+ })
+ }
+}
+
+module.exports = NoTimestamp
app/Models/User.js 39(+39 -0)
diff --git a/app/Models/User.js b/app/Models/User.js
new file mode 100644
index 0000000..2804a44
--- /dev/null
+++ b/app/Models/User.js
@@ -0,0 +1,39 @@
+'use strict'
+
+/** @type {import('@adonisjs/framework/src/Hash')} */
+const Hash = use('Hash')
+
+/** @type {typeof import('@adonisjs/lucid/src/Lucid/Model')} */
+const Model = use('Model')
+
+class User extends Model {
+ static boot () {
+ super.boot()
+
+ /**
+ * A hook to hash the user password before saving
+ * it to the database.
+ */
+ this.addHook('beforeSave', async (userInstance) => {
+ if (userInstance.dirty.password) {
+ userInstance.password = await Hash.make(userInstance.password)
+ }
+ })
+ }
+
+ /**
+ * A relationship on tokens is required for auth to
+ * work. Since features like `refreshTokens` or
+ * `rememberToken` will be saved inside the
+ * tokens table.
+ *
+ * @method tokens
+ *
+ * @return {Object}
+ */
+ tokens () {
+ return this.hasMany('App/Models/Token')
+ }
+}
+
+module.exports = User
config/app.js 243(+243 -0)
diff --git a/config/app.js b/config/app.js
new file mode 100644
index 0000000..42c63a3
--- /dev/null
+++ b/config/app.js
@@ -0,0 +1,243 @@
+'use strict'
+
+/** @type {import('@adonisjs/framework/src/Env')} */
+const Env = use('Env')
+
+module.exports = {
+
+ /*
+ |--------------------------------------------------------------------------
+ | Application Name
+ |--------------------------------------------------------------------------
+ |
+ | This value is the name of your application and can be used when you
+ | need to place the application's name in a email, view or
+ | other location.
+ |
+ */
+
+ name: Env.get('APP_NAME', 'AdonisJs'),
+
+ /*
+ |--------------------------------------------------------------------------
+ | App Key
+ |--------------------------------------------------------------------------
+ |
+ | App key is a randomly generated 16 or 32 characters long string required
+ | to encrypted cookies, sessions and other sensitive data.
+ |
+ */
+ appKey: Env.getOrFail('APP_KEY'),
+
+ http: {
+ /*
+ |--------------------------------------------------------------------------
+ | Allow Method Spoofing
+ |--------------------------------------------------------------------------
+ |
+ | Method spoofing allows you to make requests by spoofing the http verb.
+ | Which means you can make a GET request but instruct the server to
+ | treat as a POST or PUT request. If you want this feature, set the
+ | below value to true.
+ |
+ */
+ allowMethodSpoofing: true,
+
+ /*
+ |--------------------------------------------------------------------------
+ | Trust Proxy
+ |--------------------------------------------------------------------------
+ |
+ | Trust proxy defines whether X-Forwarded-* headers should be trusted or not.
+ | When your application is behind a proxy server like nginx, these values
+ | are set automatically and should be trusted. Apart from setting it
+ | to true or false Adonis supports a handful of ways to allow proxy
+ | values. Read documentation for that.
+ |
+ */
+ trustProxy: false,
+
+ /*
+ |--------------------------------------------------------------------------
+ | Subdomains
+ |--------------------------------------------------------------------------
+ |
+ | Offset to be used for returning subdomains for a given request. For
+ | majority of applications it will be 2, until you have nested
+ | sudomains.
+ | cheatsheet.adonisjs.com - offset - 2
+ | virk.cheatsheet.adonisjs.com - offset - 3
+ |
+ */
+ subdomainOffset: 2,
+
+ /*
+ |--------------------------------------------------------------------------
+ | JSONP Callback
+ |--------------------------------------------------------------------------
+ |
+ | Default jsonp callback to be used when callback query string is missing
+ | in request url.
+ |
+ */
+ jsonpCallback: 'callback',
+
+
+ /*
+ |--------------------------------------------------------------------------
+ | Etag
+ |--------------------------------------------------------------------------
+ |
+ | Set etag on all HTTP responses. In order to disable for selected routes,
+ | you can call the `response.send` with an options object as follows.
+ |
+ | response.send('Hello', { ignoreEtag: true })
+ |
+ */
+ etag: false
+ },
+
+ views: {
+ /*
+ |--------------------------------------------------------------------------
+ | Cache Views
+ |--------------------------------------------------------------------------
+ |
+ | Define whether or not to cache the compiled view. Set it to true in
+ | production to optimize view loading time.
+ |
+ */
+ cache: Env.get('CACHE_VIEWS', true)
+ },
+
+ static: {
+ /*
+ |--------------------------------------------------------------------------
+ | Dot Files
+ |--------------------------------------------------------------------------
+ |
+ | Define how to treat dot files when trying to serve static resources.
+ | By default it is set to ignore, which will pretend that dotfiles
+ | do not exist.
+ |
+ | Can be one of the following
+ | ignore, deny, allow
+ |
+ */
+ dotfiles: 'ignore',
+
+ /*
+ |--------------------------------------------------------------------------
+ | ETag
+ |--------------------------------------------------------------------------
+ |
+ | Enable or disable etag generation
+ |
+ */
+ etag: true,
+
+ /*
+ |--------------------------------------------------------------------------
+ | Extensions
+ |--------------------------------------------------------------------------
+ |
+ | Set file extension fallbacks. When set, if a file is not found, the given
+ | extensions will be added to the file name and search for. The first
+ | that exists will be served. Example: ['html', 'htm'].
+ |
+ */
+ extensions: false
+ },
+
+ locales: {
+ /*
+ |--------------------------------------------------------------------------
+ | Loader
+ |--------------------------------------------------------------------------
+ |
+ | The loader to be used for fetching and updating locales. Below is the
+ | list of available options.
+ |
+ | file, database
+ |
+ */
+ loader: 'file',
+
+ /*
+ |--------------------------------------------------------------------------
+ | Default Locale
+ |--------------------------------------------------------------------------
+ |
+ | Default locale to be used by Antl provider. You can always switch drivers
+ | in runtime or use the official Antl middleware to detect the driver
+ | based on HTTP headers/query string.
+ |
+ */
+ locale: 'en'
+ },
+
+ logger: {
+ /*
+ |--------------------------------------------------------------------------
+ | Transport
+ |--------------------------------------------------------------------------
+ |
+ | Transport to be used for logging messages. You can have multiple
+ | transports using same driver.
+ |
+ | Available drivers are: `file` and `console`.
+ |
+ */
+ transport: 'console',
+
+ /*
+ |--------------------------------------------------------------------------
+ | Console Transport
+ |--------------------------------------------------------------------------
+ |
+ | Using `console` driver for logging. This driver writes to `stdout`
+ | and `stderr`
+ |
+ */
+ console: {
+ driver: 'console',
+ name: 'adonis-app',
+ level: 'info'
+ },
+
+ /*
+ |--------------------------------------------------------------------------
+ | File Transport
+ |--------------------------------------------------------------------------
+ |
+ | File transport uses file driver and writes log messages for a given
+ | file inside `tmp` directory for your app.
+ |
+ | For a different directory, set an absolute path for the filename.
+ |
+ */
+ file: {
+ driver: 'file',
+ name: 'adonis-app',
+ filename: 'adonis.log',
+ level: 'info'
+ }
+ },
+
+ /*
+ |--------------------------------------------------------------------------
+ | Generic Cookie Options
+ |--------------------------------------------------------------------------
+ |
+ | The following cookie options are generic settings used by AdonisJs to create
+ | cookies. However, some parts of the application like `sessions` can have
+ | seperate settings for cookies inside `config/session.js`.
+ |
+ */
+ cookie: {
+ httpOnly: true,
+ sameSite: false,
+ path: '/',
+ maxAge: 7200
+ }
+}
config/auth.js 94(+94 -0)
diff --git a/config/auth.js b/config/auth.js
new file mode 100644
index 0000000..5fceb35
--- /dev/null
+++ b/config/auth.js
@@ -0,0 +1,94 @@
+'use strict'
+
+/** @type {import('@adonisjs/framework/src/Env')} */
+const Env = use('Env')
+
+module.exports = {
+ /*
+ |--------------------------------------------------------------------------
+ | Authenticator
+ |--------------------------------------------------------------------------
+ |
+ | Authentication is a combination of serializer and scheme with extra
+ | config to define on how to authenticate a user.
+ |
+ | Available Schemes - basic, session, jwt, api
+ | Available Serializers - lucid, database
+ |
+ */
+ authenticator: 'session',
+
+ /*
+ |--------------------------------------------------------------------------
+ | Session
+ |--------------------------------------------------------------------------
+ |
+ | Session authenticator makes use of sessions to authenticate a user.
+ | Session authentication is always persistent.
+ |
+ */
+ session: {
+ serializer: 'lucid',
+ model: 'App/Models/User',
+ scheme: 'session',
+ uid: 'email',
+ password: 'password'
+ },
+
+ /*
+ |--------------------------------------------------------------------------
+ | Basic Auth
+ |--------------------------------------------------------------------------
+ |
+ | The basic auth authenticator uses basic auth header to authenticate a
+ | user.
+ |
+ | NOTE:
+ | This scheme is not persistent and users are supposed to pass
+ | login credentials on each request.
+ |
+ */
+ basic: {
+ serializer: 'lucid',
+ model: 'App/Models/User',
+ scheme: 'basic',
+ uid: 'email',
+ password: 'password'
+ },
+
+ /*
+ |--------------------------------------------------------------------------
+ | Jwt
+ |--------------------------------------------------------------------------
+ |
+ | The jwt authenticator works by passing a jwt token on each HTTP request
+ | via HTTP `Authorization` header.
+ |
+ */
+ jwt: {
+ serializer: 'lucid',
+ model: 'App/Models/User',
+ scheme: 'jwt',
+ uid: 'email',
+ password: 'password',
+ options: {
+ secret: Env.get('APP_KEY')
+ }
+ },
+
+ /*
+ |--------------------------------------------------------------------------
+ | Api
+ |--------------------------------------------------------------------------
+ |
+ | The Api scheme makes use of API personal tokens to authenticate a user.
+ |
+ */
+ api: {
+ serializer: 'lucid',
+ model: 'App/Models/User',
+ scheme: 'api',
+ uid: 'email',
+ password: 'password'
+ }
+}
config/bodyParser.js 157(+157 -0)
diff --git a/config/bodyParser.js b/config/bodyParser.js
new file mode 100644
index 0000000..6b40f1a
--- /dev/null
+++ b/config/bodyParser.js
@@ -0,0 +1,157 @@
+'use strict'
+
+module.exports = {
+ /*
+ |--------------------------------------------------------------------------
+ | JSON Parser
+ |--------------------------------------------------------------------------
+ |
+ | Below settings are applied when request body contains JSON payload. If
+ | you want body parser to ignore JSON payload, then simply set `types`
+ | to an empty array.
+ */
+ json: {
+ /*
+ |--------------------------------------------------------------------------
+ | limit
+ |--------------------------------------------------------------------------
+ |
+ | Defines the limit of JSON that can be sent by the client. If payload
+ | is over 1mb it will not be processed.
+ |
+ */
+ limit: '1mb',
+
+ /*
+ |--------------------------------------------------------------------------
+ | strict
+ |--------------------------------------------------------------------------
+ |
+ | When `scrict` is set to true, body parser will only parse Arrays and
+ | Object. Otherwise everything parseable by `JSON.parse` is parsed.
+ |
+ */
+ strict: true,
+
+ /*
+ |--------------------------------------------------------------------------
+ | types
+ |--------------------------------------------------------------------------
+ |
+ | Which content types are processed as JSON payloads. You are free to
+ | add your own types here, but the request body should be parseable
+ | by `JSON.parse` method.
+ |
+ */
+ types: [
+ 'application/json',
+ 'application/json-patch+json',
+ 'application/vnd.api+json',
+ 'application/csp-report'
+ ]
+ },
+
+ /*
+ |--------------------------------------------------------------------------
+ | Raw Parser
+ |--------------------------------------------------------------------------
+ |
+ |
+ |
+ */
+ raw: {
+ types: [
+ 'text/*'
+ ]
+ },
+
+ /*
+ |--------------------------------------------------------------------------
+ | Form Parser
+ |--------------------------------------------------------------------------
+ |
+ |
+ |
+ */
+ form: {
+ types: [
+ 'application/x-www-form-urlencoded'
+ ]
+ },
+
+ /*
+ |--------------------------------------------------------------------------
+ | Files Parser
+ |--------------------------------------------------------------------------
+ |
+ |
+ |
+ */
+ files: {
+ types: [
+ 'multipart/form-data'
+ ],
+
+ /*
+ |--------------------------------------------------------------------------
+ | Max Size
+ |--------------------------------------------------------------------------
+ |
+ | Below value is the max size of all the files uploaded to the server. It
+ | is validated even before files have been processed and hard exception
+ | is thrown.
+ |
+ | Consider setting a reasonable value here, otherwise people may upload GB's
+ | of files which will keep your server busy.
+ |
+ | Also this value is considered when `autoProcess` is set to true.
+ |
+ */
+ maxSize: '20mb',
+
+ /*
+ |--------------------------------------------------------------------------
+ | Auto Process
+ |--------------------------------------------------------------------------
+ |
+ | Whether or not to auto-process files. Since HTTP servers handle files via
+ | couple of specific endpoints. It is better to set this value off and
+ | manually process the files when required.
+ |
+ | This value can contain a boolean or an array of route patterns
+ | to be autoprocessed.
+ */
+ autoProcess: true,
+
+ /*
+ |--------------------------------------------------------------------------
+ | Process Manually
+ |--------------------------------------------------------------------------
+ |
+ | The list of routes that should not process files and instead rely on
+ | manual process. This list should only contain routes when autoProcess
+ | is to true. Otherwise everything is processed manually.
+ |
+ */
+ processManually: []
+
+ /*
+ |--------------------------------------------------------------------------
+ | Temporary file name
+ |--------------------------------------------------------------------------
+ |
+ | Define a function, which should return a string to be used as the
+ | tmp file name.
+ |
+ | If not defined, Bodyparser will use `uuid` as the tmp file name.
+ |
+ | To be defined as. If you are defining the function, then do make sure
+ | to return a value from it.
+ |
+ | tmpFileName () {
+ | return 'some-unique-value'
+ | }
+ |
+ */
+ }
+}
config/cors.js 87(+87 -0)
diff --git a/config/cors.js b/config/cors.js
new file mode 100644
index 0000000..4c3848e
--- /dev/null
+++ b/config/cors.js
@@ -0,0 +1,87 @@
+'use strict'
+
+module.exports = {
+ /*
+ |--------------------------------------------------------------------------
+ | Origin
+ |--------------------------------------------------------------------------
+ |
+ | Set a list of origins to be allowed. The value can be one of the following
+ |
+ | Boolean: true - Allow current request origin
+ | Boolean: false - Disallow all
+ | String - Comma seperated list of allowed origins
+ | Array - An array of allowed origins
+ | String: * - A wildcard to allow current request origin
+ | Function - Receives the current origin and should return one of the above values.
+ |
+ */
+ origin: false,
+
+ /*
+ |--------------------------------------------------------------------------
+ | Methods
+ |--------------------------------------------------------------------------
+ |
+ | HTTP methods to be allowed. The value can be one of the following
+ |
+ | String - Comma seperated list of allowed methods
+ | Array - An array of allowed methods
+ |
+ */
+ methods: ['GET', 'PUT', 'PATCH', 'POST', 'DELETE'],
+
+ /*
+ |--------------------------------------------------------------------------
+ | Headers
+ |--------------------------------------------------------------------------
+ |
+ | List of headers to be allowed via Access-Control-Request-Headers header.
+ | The value can be on of the following.
+ |
+ | Boolean: true - Allow current request headers
+ | Boolean: false - Disallow all
+ | String - Comma seperated list of allowed headers
+ | Array - An array of allowed headers
+ | String: * - A wildcard to allow current request headers
+ | Function - Receives the current header and should return one of the above values.
+ |
+ */
+ headers: true,
+
+ /*
+ |--------------------------------------------------------------------------
+ | Expose Headers
+ |--------------------------------------------------------------------------
+ |
+ | A list of headers to be exposed via `Access-Control-Expose-Headers`
+ | header. The value can be on of the following.
+ |
+ | Boolean: false - Disallow all
+ | String: Comma seperated list of allowed headers
+ | Array - An array of allowed headers
+ |
+ */
+ exposeHeaders: false,
+
+ /*
+ |--------------------------------------------------------------------------
+ | Credentials
+ |--------------------------------------------------------------------------
+ |
+ | Define Access-Control-Allow-Credentials header. It should always be a
+ | boolean.
+ |
+ */
+ credentials: false,
+
+ /*
+ |--------------------------------------------------------------------------
+ | MaxAge
+ |--------------------------------------------------------------------------
+ |
+ | Define Access-Control-Allow-Max-Age
+ |
+ */
+ maxAge: 90
+}
config/database.js 81(+81 -0)
diff --git a/config/database.js b/config/database.js
new file mode 100644
index 0000000..e9cb916
--- /dev/null
+++ b/config/database.js
@@ -0,0 +1,81 @@
+'use strict'
+
+/** @type {import('@adonisjs/framework/src/Env')} */
+const Env = use('Env')
+
+/** @type {import('@adonisjs/ignitor/src/Helpers')} */
+const Helpers = use('Helpers')
+
+module.exports = {
+ /*
+ |--------------------------------------------------------------------------
+ | Default Connection
+ |--------------------------------------------------------------------------
+ |
+ | Connection defines the default connection settings to be used while
+ | interacting with SQL databases.
+ |
+ */
+ connection: Env.get('DB_CONNECTION', 'sqlite'),
+
+ /*
+ |--------------------------------------------------------------------------
+ | Sqlite
+ |--------------------------------------------------------------------------
+ |
+ | Sqlite is a flat file database and can be good choice under development
+ | environment.
+ |
+ | npm i --save sqlite3
+ |
+ */
+ sqlite: {
+ client: 'sqlite3',
+ connection: {
+ filename: Helpers.databasePath(`${Env.get('DB_DATABASE', 'development')}.sqlite`)
+ },
+ useNullAsDefault: true
+ },
+
+ /*
+ |--------------------------------------------------------------------------
+ | MySQL
+ |--------------------------------------------------------------------------
+ |
+ | Here we define connection settings for MySQL database.
+ |
+ | npm i --save mysql
+ |
+ */
+ mysql: {
+ client: 'mysql',
+ connection: {
+ host: Env.get('DB_HOST', 'localhost'),
+ port: Env.get('DB_PORT', ''),
+ user: Env.get('DB_USER', 'root'),
+ password: Env.get('DB_PASSWORD', ''),
+ database: Env.get('DB_DATABASE', 'adonis')
+ }
+ },
+
+ /*
+ |--------------------------------------------------------------------------
+ | PostgreSQL
+ |--------------------------------------------------------------------------
+ |
+ | Here we define connection settings for PostgreSQL database.
+ |
+ | npm i --save pg
+ |
+ */
+ pg: {
+ client: 'pg',
+ connection: {
+ host: Env.get('DB_HOST', 'localhost'),
+ port: Env.get('DB_PORT', ''),
+ user: Env.get('DB_USER', 'root'),
+ password: Env.get('DB_PASSWORD', ''),
+ database: Env.get('DB_DATABASE', 'adonis')
+ }
+ }
+}
config/hash.js 49(+49 -0)
diff --git a/config/hash.js b/config/hash.js
new file mode 100644
index 0000000..42f5805
--- /dev/null
+++ b/config/hash.js
@@ -0,0 +1,49 @@
+'use strict'
+
+/** @type {import('@adonisjs/framework/src/Env')} */
+const Env = use('Env')
+
+module.exports = {
+ /*
+ |--------------------------------------------------------------------------
+ | Driver
+ |--------------------------------------------------------------------------
+ |
+ | Driver to be used for hashing values. The same driver is used by the
+ | auth module too.
+ |
+ */
+ driver: Env.get('HASH_DRIVER', 'bcrypt'),
+
+ /*
+ |--------------------------------------------------------------------------
+ | Bcrypt
+ |--------------------------------------------------------------------------
+ |
+ | Config related to bcrypt hashing. https://www.npmjs.com/package/bcrypt
+ | package is used internally.
+ |
+ */
+ bcrypt: {
+ rounds: 10
+ },
+
+ /*
+ |--------------------------------------------------------------------------
+ | Argon
+ |--------------------------------------------------------------------------
+ |
+ | Config related to argon. https://www.npmjs.com/package/argon2 package is
+ | used internally.
+ |
+ | Since argon is optional, you will have to install the dependency yourself
+ |
+ |============================================================================
+ | npm i argon2
+ |============================================================================
+ |
+ */
+ argon: {
+ type: 1
+ }
+}
config/session.js 101(+101 -0)
diff --git a/config/session.js b/config/session.js
new file mode 100644
index 0000000..30d6bab
--- /dev/null
+++ b/config/session.js
@@ -0,0 +1,101 @@
+'use strict'
+
+/** @type {import('@adonisjs/framework/src/Env')} */
+const Env = use('Env')
+
+module.exports = {
+ /*
+ |--------------------------------------------------------------------------
+ | Session Driver
+ |--------------------------------------------------------------------------
+ |
+ | The session driver to be used for storing session values. It can be
+ | cookie, file or redis.
+ |
+ | For `redis` driver, make sure to install and register `@adonisjs/redis`
+ |
+ */
+ driver: Env.get('SESSION_DRIVER', 'cookie'),
+
+ /*
+ |--------------------------------------------------------------------------
+ | Cookie Name
+ |--------------------------------------------------------------------------
+ |
+ | The name of the cookie to be used for saving session id. Session ids
+ | are signed and encrypted.
+ |
+ */
+ cookieName: 'adonis-session',
+
+ /*
+ |--------------------------------------------------------------------------
+ | Clear session when browser closes
+ |--------------------------------------------------------------------------
+ |
+ | If this value is true, the session cookie will be temporary and will be
+ | removed when browser closes.
+ |
+ */
+ clearWithBrowser: true,
+
+ /*
+ |--------------------------------------------------------------------------
+ | Session age
+ |--------------------------------------------------------------------------
+ |
+ | This value is only used when `clearWithBrowser` is set to false. The
+ | age must be a valid https://npmjs.org/package/ms string or should
+ | be in milliseconds.
+ |
+ | Valid values are:
+ | '2h', '10d', '5y', '2.5 hrs'
+ |
+ */
+ age: '2h',
+
+ /*
+ |--------------------------------------------------------------------------
+ | Cookie options
+ |--------------------------------------------------------------------------
+ |
+ | Cookie options defines the options to be used for setting up session
+ | cookie
+ |
+ */
+ cookie: {
+ httpOnly: true,
+ sameSite: false,
+ path: '/'
+ },
+
+ /*
+ |--------------------------------------------------------------------------
+ | Sessions location
+ |--------------------------------------------------------------------------
+ |
+ | If driver is set to file, we need to define the relative location from
+ | the temporary path or absolute url to any location.
+ |
+ */
+ file: {
+ location: 'sessions'
+ },
+
+ /*
+ |--------------------------------------------------------------------------
+ | Redis config
+ |--------------------------------------------------------------------------
+ |
+ | The configuration for the redis driver. By default we reference it from
+ | the redis file. But you are free to define an object here too.
+ |
+ */
+ redis: {
+ host: '127.0.0.1',
+ port: 6379,
+ password: null,
+ db: 0,
+ keyPrefix: ''
+ }
+}
config/shield.js 145(+145 -0)
diff --git a/config/shield.js b/config/shield.js
new file mode 100644
index 0000000..255cee3
--- /dev/null
+++ b/config/shield.js
@@ -0,0 +1,145 @@
+'use strict'
+
+module.exports = {
+ /*
+ |--------------------------------------------------------------------------
+ | Content Security Policy
+ |--------------------------------------------------------------------------
+ |
+ | Content security policy filters out the origins not allowed to execute
+ | and load resources like scripts, styles and fonts. There are wide
+ | variety of options to choose from.
+ */
+ csp: {
+ /*
+ |--------------------------------------------------------------------------
+ | Directives
+ |--------------------------------------------------------------------------
+ |
+ | All directives are defined in camelCase and here is the list of
+ | available directives and their possible values.
+ |
+ | https://content-security-policy.com
+ |
+ | @example
+ | directives: {
+ | defaultSrc: ['self', '@nonce', 'cdnjs.cloudflare.com']
+ | }
+ |
+ */
+ directives: {
+ },
+ /*
+ |--------------------------------------------------------------------------
+ | Report only
+ |--------------------------------------------------------------------------
+ |
+ | Setting `reportOnly=true` will not block the scripts from running and
+ | instead report them to a URL.
+ |
+ */
+ reportOnly: false,
+ /*
+ |--------------------------------------------------------------------------
+ | Set all headers
+ |--------------------------------------------------------------------------
+ |
+ | Headers staring with `X` have been depreciated, since all major browsers
+ | supports the standard CSP header. So its better to disable deperciated
+ | headers, unless you want them to be set.
+ |
+ */
+ setAllHeaders: false,
+
+ /*
+ |--------------------------------------------------------------------------
+ | Disable on android
+ |--------------------------------------------------------------------------
+ |
+ | Certain versions of android are buggy with CSP policy. So you can set
+ | this value to true, to disable it for Android versions with buggy
+ | behavior.
+ |
+ | Here is an issue reported on a different package, but helpful to read
+ | if you want to know the behavior. https://github.com/helmetjs/helmet/pull/82
+ |
+ */
+ disableAndroid: true
+ },
+
+ /*
+ |--------------------------------------------------------------------------
+ | X-XSS-Protection
+ |--------------------------------------------------------------------------
+ |
+ | X-XSS Protection saves applications from XSS attacks. It is adopted
+ | by IE and later followed by some other browsers.
+ |
+ | Learn more at https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-XSS-Protection
+ |
+ */
+ xss: {
+ enabled: true,
+ enableOnOldIE: false
+ },
+
+ /*
+ |--------------------------------------------------------------------------
+ | Iframe Options
+ |--------------------------------------------------------------------------
+ |
+ | xframe defines whether or not your website can be embedded inside an
+ | iframe. Choose from one of the following options.
+ | @available options
+ | DENY, SAMEORIGIN, ALLOW-FROM http://example.com
+ |
+ | Learn more at https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options
+ */
+ xframe: 'DENY',
+
+ /*
+ |--------------------------------------------------------------------------
+ | No Sniff
+ |--------------------------------------------------------------------------
+ |
+ | Browsers have a habit of sniffing content-type of a response. Which means
+ | files with .txt extension containing Javascript code will be executed as
+ | Javascript. You can disable this behavior by setting nosniff to false.
+ |
+ | Learn more at https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options
+ |
+ */
+ nosniff: true,
+
+ /*
+ |--------------------------------------------------------------------------
+ | No Open
+ |--------------------------------------------------------------------------
+ |
+ | IE users can execute webpages in the context of your website, which is
+ | a serious security risk. Below option will manage this for you.
+ |
+ */
+ noopen: true,
+
+ /*
+ |--------------------------------------------------------------------------
+ | CSRF Protection
+ |--------------------------------------------------------------------------
+ |
+ | CSRF Protection adds another layer of security by making sure, actionable
+ | routes does have a valid token to execute an action.
+ |
+ */
+ csrf: {
+ enable: true,
+ methods: ['POST', 'PUT', 'DELETE'],
+ filterUris: [],
+ cookieOptions: {
+ httpOnly: false,
+ sameSite: true,
+ path: '/',
+ maxAge: 7200
+ }
+ }
+}
database/factory.js 21(+21 -0)
diff --git a/database/factory.js b/database/factory.js
new file mode 100644
index 0000000..16b5084
--- /dev/null
+++ b/database/factory.js
@@ -0,0 +1,21 @@
+'use strict'
+
+/*
+|--------------------------------------------------------------------------
+| Factory
+|--------------------------------------------------------------------------
+|
+| Factories are used to define blueprints for database tables or Lucid
+| models. Later you can use these blueprints to seed your database
+| with dummy data.
+|
+*/
+
+/** @type {import('@adonisjs/lucid/src/Factory')} */
+// const Factory = use('Factory')
+
+// Factory.blueprint('App/Models/User', (faker) => {
+// return {
+// username: faker.username()
+// }
+// })
database/migrations/1503248427885_user.js 22(+22 -0)
diff --git a/database/migrations/1503248427885_user.js b/database/migrations/1503248427885_user.js
new file mode 100644
index 0000000..1ade2f5
--- /dev/null
+++ b/database/migrations/1503248427885_user.js
@@ -0,0 +1,22 @@
+'use strict'
+
+/** @type {import('@adonisjs/lucid/src/Schema')} */
+const Schema = use('Schema')
+
+class UserSchema extends Schema {
+ up () {
+ this.create('users', (table) => {
+ table.increments()
+ table.string('username', 80).notNullable().unique()
+ table.string('email', 254).notNullable().unique()
+ table.string('password', 60).notNullable()
+ table.timestamps()
+ })
+ }
+
+ down () {
+ this.drop('users')
+ }
+}
+
+module.exports = UserSchema
database/migrations/1503248427886_token.js 23(+23 -0)
diff --git a/database/migrations/1503248427886_token.js b/database/migrations/1503248427886_token.js
new file mode 100644
index 0000000..c8bb9fc
--- /dev/null
+++ b/database/migrations/1503248427886_token.js
@@ -0,0 +1,23 @@
+'use strict'
+
+/** @type {import('@adonisjs/lucid/src/Schema')} */
+const Schema = use('Schema')
+
+class TokensSchema extends Schema {
+ up () {
+ this.create('tokens', (table) => {
+ table.increments()
+ table.integer('user_id').unsigned().references('id').inTable('users')
+ table.string('token', 255).notNullable().unique().index()
+ table.string('type', 80).notNullable()
+ table.boolean('is_revoked').defaultTo(false)
+ table.timestamps()
+ })
+ }
+
+ down () {
+ this.drop('tokens')
+ }
+}
+
+module.exports = TokensSchema
diff --git a/database/migrations/1575321261885_themes_schema.js b/database/migrations/1575321261885_themes_schema.js
new file mode 100644
index 0000000..bdc0da5
--- /dev/null
+++ b/database/migrations/1575321261885_themes_schema.js
@@ -0,0 +1,19 @@
+'use strict'
+
+/** @type {import('@adonisjs/lucid/src/Schema')} */
+const Schema = use('Schema')
+
+class ThemesSchema extends Schema {
+ up () {
+ this.create('themes', (table) => {
+ table.increments('id')
+ table.string('name').notNullable().unique()
+ })
+ }
+
+ down () {
+ this.drop('themes')
+ }
+}
+
+module.exports = ThemesSchema
diff --git a/database/migrations/1575321574938_elements_schema.js b/database/migrations/1575321574938_elements_schema.js
new file mode 100644
index 0000000..a7f54f7
--- /dev/null
+++ b/database/migrations/1575321574938_elements_schema.js
@@ -0,0 +1,22 @@
+'use strict'
+
+/** @type {import('@adonisjs/lucid/src/Schema')} */
+const Schema = use('Schema')
+
+class ElementsSchema extends Schema {
+ up () {
+ this.create('elements', (table) => {
+ table.increments('id')
+ table.string('name').notNullable()
+ table.integer('theme_id').notNullable().unsigned().references('id').inTable('themes')
+ table.integer('priority').nullable().unsigned()
+ table.integer('refresh_rate').nullable()
+ })
+ }
+
+ down () {
+ this.drop('elements')
+ }
+}
+
+module.exports = ElementsSchema
diff --git a/database/migrations/1575321954825_element_notes_schema.js b/database/migrations/1575321954825_element_notes_schema.js
new file mode 100644
index 0000000..6a4ecfc
--- /dev/null
+++ b/database/migrations/1575321954825_element_notes_schema.js
@@ -0,0 +1,21 @@
+'use strict'
+
+/** @type {import('@adonisjs/lucid/src/Schema')} */
+const Schema = use('Schema')
+
+class ElementNotesSchema extends Schema {
+ up () {
+ this.create('element_notes', (table) => {
+ table.increments('id')
+ table.integer('element_id').notNullable().unsigned().references('id').inTable('elements')
+ table.text('content').notNullable()
+ table.timestamps()
+ })
+ }
+
+ down () {
+ this.drop('element_notes')
+ }
+}
+
+module.exports = ElementNotesSchema
diff --git a/database/migrations/1575322085612_standards_schema.js b/database/migrations/1575322085612_standards_schema.js
new file mode 100644
index 0000000..31b756a
--- /dev/null
+++ b/database/migrations/1575322085612_standards_schema.js
@@ -0,0 +1,23 @@
+'use strict'
+
+/** @type {import('@adonisjs/lucid/src/Schema')} */
+const Schema = use('Schema')
+
+class StandardsSchema extends Schema {
+ up () {
+ this.create('standards', (table) => {
+ table.increments('id')
+ table.integer('element_id').notNullable().unsigned().references('id').inTable('elements')
+ table.string('document').notNullable()
+ table.float('version', 2).unsigned().notNullable()
+ table.timestamps()
+ table.date('retired').nullable()
+ })
+ }
+
+ down () {
+ this.drop('standards')
+ }
+}
+
+module.exports = StandardsSchema
diff --git a/database/migrations/1575322303589_standards_notes_schema.js b/database/migrations/1575322303589_standards_notes_schema.js
new file mode 100644
index 0000000..f0ed7b7
--- /dev/null
+++ b/database/migrations/1575322303589_standards_notes_schema.js
@@ -0,0 +1,21 @@
+'use strict'
+
+/** @type {import('@adonisjs/lucid/src/Schema')} */
+const Schema = use('Schema')
+
+class StandardsNotesSchema extends Schema {
+ up () {
+ this.create('standards_notes', (table) => {
+ table.increments('id')
+ table.integer('standard_id').notNullable().unsigned().references('id').inTable('standards')
+ table.text('content').notNullable()
+ table.timestamps()
+ })
+ }
+
+ down () {
+ this.drop('standards_notes')
+ }
+}
+
+module.exports = StandardsNotesSchema
diff --git a/database/migrations/1575322481931_organization_types_schema.js b/database/migrations/1575322481931_organization_types_schema.js
new file mode 100644
index 0000000..ac46e44
--- /dev/null
+++ b/database/migrations/1575322481931_organization_types_schema.js
@@ -0,0 +1,19 @@
+'use strict'
+
+/** @type {import('@adonisjs/lucid/src/Schema')} */
+const Schema = use('Schema')
+
+class OrganizationTypesSchema extends Schema {
+ up () {
+ this.create('organization_types', (table) => {
+ table.increments('id')
+ table.string('type').notNullable()
+ })
+ }
+
+ down () {
+ this.drop('organization_types')
+ }
+}
+
+module.exports = OrganizationTypesSchema
diff --git a/database/migrations/1575322618141_organizations_schema.js b/database/migrations/1575322618141_organizations_schema.js
new file mode 100644
index 0000000..51fe867
--- /dev/null
+++ b/database/migrations/1575322618141_organizations_schema.js
@@ -0,0 +1,23 @@
+'use strict'
+
+/** @type {import('@adonisjs/lucid/src/Schema')} */
+const Schema = use('Schema')
+
+class OrganizationsSchema extends Schema {
+ up () {
+ this.create('organizations', (table) => {
+ table.increments('id')
+ table.string('name').notNullable().unique()
+ table.string('email').notNullable()
+ table.string('phone').notNullable()
+ table.integer('organization_type_id').notNullable().references('id').inTable('organization_types')
+ table.timestamps()
+ })
+ }
+
+ down () {
+ this.drop('organizations')
+ }
+}
+
+module.exports = OrganizationsSchema
diff --git a/database/migrations/1575322806187_contacts_schema.js b/database/migrations/1575322806187_contacts_schema.js
new file mode 100644
index 0000000..06b7ca8
--- /dev/null
+++ b/database/migrations/1575322806187_contacts_schema.js
@@ -0,0 +1,24 @@
+'use strict'
+
+/** @type {import('@adonisjs/lucid/src/Schema')} */
+const Schema = use('Schema')
+
+class ContactsSchema extends Schema {
+ up () {
+ this.create('contacts', (table) => {
+ table.increments('id')
+ table.string('email').notNullable().unique()
+ table.string('first_name').notNullable()
+ table.string('last_name').notNullable()
+ table.string('phone').notNullable()
+ table.integer('organization_id').notNullable().references('id').inTable('organizations')
+ table.timestamps()
+ })
+ }
+
+ down () {
+ this.drop('contacts')
+ }
+}
+
+module.exports = ContactsSchema
diff --git a/database/migrations/1575322970641_contact_notes_schema.js b/database/migrations/1575322970641_contact_notes_schema.js
new file mode 100644
index 0000000..fdec2d8
--- /dev/null
+++ b/database/migrations/1575322970641_contact_notes_schema.js
@@ -0,0 +1,21 @@
+'use strict'
+
+/** @type {import('@adonisjs/lucid/src/Schema')} */
+const Schema = use('Schema')
+
+class ContactNotesSchema extends Schema {
+ up () {
+ this.create('contact_notes', (table) => {
+ table.increments('id')
+ table.integer('contact_id').notNullable().unsigned().references('id').inTable('contacts')
+ table.text('content').notNullable()
+ table.timestamps()
+ })
+ }
+
+ down () {
+ this.drop('contact_notes')
+ }
+}
+
+module.exports = ContactNotesSchema
diff --git a/database/migrations/1575323184990_funding_schema.js b/database/migrations/1575323184990_funding_schema.js
new file mode 100644
index 0000000..583dd4d
--- /dev/null
+++ b/database/migrations/1575323184990_funding_schema.js
@@ -0,0 +1,23 @@
+'use strict'
+
+/** @type {import('@adonisjs/lucid/src/Schema')} */
+const Schema = use('Schema')
+
+class FundingSchema extends Schema {
+ up () {
+ this.create('fundings', (table) => {
+ table.increments('id')
+ table.float('amount', 2).notNullable()
+ table.string('document').notNullable()
+ table.date('date_awarded').notNullable()
+ table.integer('element_id').notNullable().references('id').inTable('elements')
+ table.timestamps()
+ })
+ }
+
+ down () {
+ this.drop('fundings')
+ }
+}
+
+module.exports = FundingSchema
diff --git a/database/migrations/1575323309230_stewards_schema.js b/database/migrations/1575323309230_stewards_schema.js
new file mode 100644
index 0000000..6ec71a6
--- /dev/null
+++ b/database/migrations/1575323309230_stewards_schema.js
@@ -0,0 +1,22 @@
+'use strict'
+
+/** @type {import('@adonisjs/lucid/src/Schema')} */
+const Schema = use('Schema')
+
+class StewardsSchema extends Schema {
+ up () {
+ this.create('stewards', (table) => {
+ table.increments('id')
+ table.integer('contact_id').notNullable().references('id').inTable('contacts')
+ table.date('start_date').notNullable()
+ table.date('end_date').notNullable()
+ table.timestamps()
+ })
+ }
+
+ down () {
+ this.drop('stewards')
+ }
+}
+
+module.exports = StewardsSchema
diff --git a/database/migrations/1575323434337_elements_stewards_schema.js b/database/migrations/1575323434337_elements_stewards_schema.js
new file mode 100644
index 0000000..1077dd7
--- /dev/null
+++ b/database/migrations/1575323434337_elements_stewards_schema.js
@@ -0,0 +1,19 @@
+'use strict'
+
+/** @type {import('@adonisjs/lucid/src/Schema')} */
+const Schema = use('Schema')
+
+class ElementsStewardsSchema extends Schema {
+ up () {
+ this.create('elements_stewards', (table) => {
+ table.integer('element_id').references('id').inTable('elements')
+ table.integer('steward_id').references('id').inTable('stewards')
+ })
+ }
+
+ down () {
+ this.drop('elements_stewards')
+ }
+}
+
+module.exports = ElementsStewardsSchema
diff --git a/database/migrations/1575323518345_submission_status_schema.js b/database/migrations/1575323518345_submission_status_schema.js
new file mode 100644
index 0000000..c12e740
--- /dev/null
+++ b/database/migrations/1575323518345_submission_status_schema.js
@@ -0,0 +1,20 @@
+'use strict'
+
+/** @type {import('@adonisjs/lucid/src/Schema')} */
+const Schema = use('Schema')
+
+class SubmissionStatusSchema extends Schema {
+ up () {
+ this.create('submission_statuses', (table) => {
+ table.increments()
+ table.string('status').notNullable().unique()
+ table.timestamps()
+ })
+ }
+
+ down () {
+ this.drop('submission_statuses')
+ }
+}
+
+module.exports = SubmissionStatusSchema
diff --git a/database/migrations/1575323565424_submissions_schema.js b/database/migrations/1575323565424_submissions_schema.js
new file mode 100644
index 0000000..7f53eb6
--- /dev/null
+++ b/database/migrations/1575323565424_submissions_schema.js
@@ -0,0 +1,33 @@
+'use strict'
+
+/** @type {import('@adonisjs/lucid/src/Schema')} */
+const Schema = use('Schema')
+
+class SubmissionsSchema extends Schema {
+ up () {
+ this.create('submissions', (table) => {
+ table.increments('id')
+ table.string('name')
+ table.integer('element_id').notNullable().references('id').inTable('elements')
+ table.integer('steward_id').notNullable().references('id').inTable('stewards')
+ table.date('upload_date').notNullable()
+ table.date('creation_date').notNullable()
+ table.date('published_date').notNullable()
+ table.json('metadata').nullable()
+ table.string('local_file_location').nullable()
+ table.string('download_file_location').nullable()
+ table.string('service_location_ags').nullable()
+ table.string('service_location_agol').nullable()
+ table.integer('standard_id').references('id').inTable('standards').nullable()
+ table.boolean('public').notNullable()
+ table.integer('status_id').notNullable().references('id').inTable('submission_statuses')
+ table.timestamps()
+ })
+ }
+
+ down () {
+ this.drop('submissions')
+ }
+}
+
+module.exports = SubmissionsSchema
diff --git a/database/migrations/1575323907842_submission_notes_schema.js b/database/migrations/1575323907842_submission_notes_schema.js
new file mode 100644
index 0000000..03c13ee
--- /dev/null
+++ b/database/migrations/1575323907842_submission_notes_schema.js
@@ -0,0 +1,21 @@
+'use strict'
+
+/** @type {import('@adonisjs/lucid/src/Schema')} */
+const Schema = use('Schema')
+
+class SubmissionNotesSchema extends Schema {
+ up () {
+ this.create('submission_notes', (table) => {
+ table.increments('id')
+ table.integer('submission_id').notNullable().unsigned().references('id').inTable('submissions')
+ table.text('content').notNullable()
+ table.timestamps()
+ })
+ }
+
+ down () {
+ this.drop('submission_notes')
+ }
+}
+
+module.exports = SubmissionNotesSchema
package.json 35(+35 -0)
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..d4743c3
--- /dev/null
+++ b/package.json
@@ -0,0 +1,35 @@
+{
+ "name": "adonis-fullstack-app",
+ "version": "4.1.0",
+ "adonis-version": "4.1.0",
+ "description": "The fullstack application boilerplate for Adonisjs",
+ "main": "index.js",
+ "scripts": {
+ "start": "node server.js",
+ "test": "node ace test"
+ },
+ "keywords": [
+ "adonisjs",
+ "adonis-app"
+ ],
+ "author": "",
+ "license": "UNLICENSED",
+ "private": true,
+ "dependencies": {
+ "@adonisjs/ace": "^5.0.8",
+ "@adonisjs/auth": "^3.0.7",
+ "@adonisjs/bodyparser": "^2.0.5",
+ "@adonisjs/cors": "^1.0.7",
+ "@adonisjs/fold": "^4.0.9",
+ "@adonisjs/framework": "^5.0.9",
+ "@adonisjs/ignitor": "^2.0.8",
+ "@adonisjs/lucid": "^6.1.3",
+ "@adonisjs/session": "^1.0.27",
+ "@adonisjs/shield": "^1.0.8",
+ "pg": "^7.14.0"
+ },
+ "devDependencies": {},
+ "autoload": {
+ "App": "./app"
+ }
+}
public/css/main.css 1(+1 -0)
diff --git a/public/css/main.css b/public/css/main.css
new file mode 100644
index 0000000..4328a91
--- /dev/null
+++ b/public/css/main.css
@@ -0,0 +1 @@
+/* main.css */
\ No newline at end of file
public/logo.svg 1(+1 -0)
diff --git a/public/logo.svg b/public/logo.svg
new file mode 100644
index 0000000..c8be274
--- /dev/null
+++ b/public/logo.svg
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><svg width="36px" height="33px" viewBox="0 0 36 33" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><g transform="translate(0 .5)" fill="none" fill-rule="evenodd"><path d="M20 2.236L5.618 31h28.764L20 2.236z" stroke="#FFFFFF" stroke-width="2"/><path fill="#FFFFFF" d="M12 2l12 24H0"/></g></svg>
public/pyramid.png 0(+0 -0)
diff --git a/public/pyramid.png b/public/pyramid.png
new file mode 100644
index 0000000..369ab18
Binary files /dev/null and b/public/pyramid.png differ
public/splash.png 0(+0 -0)
diff --git a/public/splash.png b/public/splash.png
new file mode 100644
index 0000000..7ea4fe0
Binary files /dev/null and b/public/splash.png differ
public/style.css 92(+92 -0)
diff --git a/public/style.css b/public/style.css
new file mode 100644
index 0000000..c805815
--- /dev/null
+++ b/public/style.css
@@ -0,0 +1,92 @@
+@import url('https://fonts.googleapis.com/css?family=Montserrat:300');
+
+html, body {
+ height: 100%;
+ width: 100%;
+}
+
+body {
+ font-family: 'Montserrat', sans-serif;
+ font-weight: 300;
+ background-image: url("/splash.png");
+ background-color: #220052;
+}
+
+* {
+ margin: 0;
+ padding: 0;
+}
+
+section {
+ height: 100%;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ max-width: 536px;
+ margin: auto;
+ position: relative;
+}
+
+section:before {
+ content: "";
+ position: absolute;
+ background: url("/pyramid.png") no-repeat;
+ background-size: 100%;
+ width: 100%;
+ height: 402px;
+ z-index: -1;
+}
+
+.logo {
+ background: url("/logo.svg") no-repeat;
+ width: 36px;
+ height: 33px;
+ background-size: 100%;
+ margin-bottom: 35px;
+ opacity: 0;
+ animation: slideUp 1s cubic-bezier(0.19, 1, 0.30, 1) 1.3s forwards;
+}
+
+.title {
+ background: url("/title.svg") no-repeat;
+ width: 219px;
+ height: 36px;
+ background-size: 100%;
+ opacity: 0;
+ animation: slideUp 1s cubic-bezier(0.19, 1, 0.30, 1) 0.2s forwards;
+}
+
+.subtitle {
+ margin-top: 25px;
+ color: #BDB3CB;
+ font-size: 17px;
+ text-align: center;
+ letter-spacing: 0.5;
+ opacity: 0;
+ animation: slideUp 1s cubic-bezier(0.19, 1, 0.30, 1) 0.5s forwards;
+}
+
+
+a {
+ color: inherit;
+ text-decoration: underline;
+}
+
+p {
+ margin: 0.83rem 0;
+}
+
+@keyframes slideUp {
+ 0% {
+ transform: translateY(40px);
+ opacity: 0;
+ }
+ 50% {
+ opacity: 0.2%;
+ }
+ 100% {
+ opacity: 1;
+ transform: none;
+ }
+}
public/title.svg 1(+1 -0)
diff --git a/public/title.svg b/public/title.svg
new file mode 100644
index 0000000..38dea69
--- /dev/null
+++ b/public/title.svg
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><svg width="186px" height="31px" viewBox="0 0 186 31" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M20.25 6.106V.1H.72v6.006h5.712v17.388H.72V29.5h19.53v-6.006h-5.712V6.106h5.712zm18.774 7.35v-5.46h-6.846V1.528h-7.182v3.108c0 2.226-1.218 3.36-3.444 3.36h-.084v5.46h3.528v8.904c0 4.578 3.528 7.686 8.82 7.686 1.932 0 3.276-.126 5.208-1.05v-5.964c-2.016.882-2.982.966-3.822.966-1.806 0-3.024-1.008-3.024-2.898v-7.644h6.846zm37.17-5.46l-3.612 13.692L68.76 7.996H63.3l-3.822 13.692-3.654-13.692h-7.308L55.068 29.5h7.266l3.696-12.516L69.684 29.5h7.308l6.552-21.504h-7.35zM95.43 7.45c6.846 0 11.424 4.746 11.424 11.256 0 6.552-4.578 11.34-11.424 11.34-6.888 0-11.466-4.788-11.466-11.34 0-6.51 4.578-11.256 11.466-11.256zm0 5.628c-2.898 0-4.62 2.352-4.62 5.628 0 3.318 1.722 5.712 4.62 5.712 2.856 0 4.578-2.394 4.578-5.712 0-3.276-1.722-5.628-4.578-5.628zm22.092.714V7.996h-7.182V29.5h7.182v-7.518c0-5.376 1.89-7.728 8.946-6.972V7.534c-4.788 0-7.686 1.806-8.946 6.258zM145.158 29.5h8.4l-7.812-11.886 7.14-9.618h-8.316l-4.284 6.552h-3.612V.1h-7.182v29.4h7.182v-8.442h3.612l4.872 8.442zm22.092-14.196h6.384c-.462-5.46-4.326-7.854-9.87-7.854-6.09 0-9.534 2.436-9.534 6.804 0 4.998 4.494 5.586 8.19 6.426 3.822.882 4.704 1.134 4.704 2.478 0 1.512-1.428 1.932-2.982 1.932-2.394 0-3.822-.966-4.074-3.486h-6.384c.336 5.88 4.536 8.442 10.542 8.442 6.132 0 9.66-2.688 9.66-7.14 0-4.998-4.41-5.628-8.736-6.594-3.234-.672-4.326-.882-4.326-2.31 0-1.134 1.176-1.848 2.856-1.848 2.268 0 3.276.882 3.57 3.15zm11.424 4.536h6.258L185.94.1h-8.316l1.05 19.74zm-.63 9.66h7.518v-6.51h-7.518v6.51z" fill="#FFFFFF" fill-rule="evenodd"/></svg>
README.md 31(+31 -0)
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..d78d10e
--- /dev/null
+++ b/README.md
@@ -0,0 +1,31 @@
+# Adonis fullstack application
+
+This is the fullstack boilerplate for AdonisJs, it comes pre-configured with.
+
+1. Bodyparser
+2. Session
+3. Authentication
+4. Web security middleware
+5. CORS
+6. Edge template engine
+7. Lucid ORM
+8. Migrations and seeds
+
+## Setup
+
+Use the adonis command to install the blueprint
+
+```bash
+adonis new yardstick
+```
+
+or manually clone the repo and then run `npm install`.
+
+
+### Migrations
+
+Run the following command to run startup migrations.
+
+```js
+adonis migration:run
+```
resources/views/inc/footer.edge 1(+1 -0)
diff --git a/resources/views/inc/footer.edge b/resources/views/inc/footer.edge
new file mode 100644
index 0000000..2337a3d
--- /dev/null
+++ b/resources/views/inc/footer.edge
@@ -0,0 +1 @@
+<footer class="footer has-text-centered">Oregon Geospatial Enterprise Office</footer>
\ No newline at end of file
resources/views/inc/nav.edge 6(+6 -0)
diff --git a/resources/views/inc/nav.edge b/resources/views/inc/nav.edge
new file mode 100644
index 0000000..2737bf1
--- /dev/null
+++ b/resources/views/inc/nav.edge
@@ -0,0 +1,6 @@
+<section class="box">
+ <h1 class="is-size-4">Data Inventory Tracking</h1>
+</section>
+<ul>
+ <li>Navigation Link</li>
+</ul>
\ No newline at end of file
resources/views/index.edge 7(+7 -0)
diff --git a/resources/views/index.edge b/resources/views/index.edge
new file mode 100644
index 0000000..62ac5e1
--- /dev/null
+++ b/resources/views/index.edge
@@ -0,0 +1,7 @@
+@layout('layouts.main')
+
+@section('content')
+
+Welcome to the Oregon Geospatial Enterprise office data inventory tracking page.
+
+@endsection
\ No newline at end of file
resources/views/layouts/main.edge 31(+31 -0)
diff --git a/resources/views/layouts/main.edge b/resources/views/layouts/main.edge
new file mode 100644
index 0000000..9d391bd
--- /dev/null
+++ b/resources/views/layouts/main.edge
@@ -0,0 +1,31 @@
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <meta http-equiv="X-UA-Compatible" content="ie=edge">
+ <meta name="description" content="ArcGIS Online Configuration Backups for Versioning and Recovery">
+ <meta name="keywords" content="arcgis, backup, arcgis online, esri, recovery, versioning, tool, agol">
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.5/css/bulma.min.css" integrity="sha256-vK3UTo/8wHbaUn+dTQD0X6dzidqc5l7gczvH+Bnowwk=" crossorigin="anonymous" />
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/cash/4.1.2/cash.min.js"></script>
+ <title>navigatOR Data Inventory Tracking</title>
+ {{ style('css/main.css') }}
+ @!section('head')
+</head>
+<body class='container'>
+ <div class="content">
+ <div class="columns">
+ <div class="column is-3">
+ <!-- Navigation Left Column -->
+ @include('inc.nav')
+ </div>
+ <div class="column is-9">
+ <!-- Main Right Column -->
+ @!section('content')
+ </div>
+ </div>
+ @include('inc.footer')
+ </div>
+@!section('scripts')
+{{ script('js/main.js') }}
+</body>
+</html>
\ No newline at end of file
resources/views/welcome.edge 20(+20 -0)
diff --git a/resources/views/welcome.edge b/resources/views/welcome.edge
new file mode 100644
index 0000000..4355627
--- /dev/null
+++ b/resources/views/welcome.edge
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8" />
+ <title>Hello Adonis</title>
+ {{ style('style') }}
+</head>
+<body>
+ <section>
+ <div class="logo"></div>
+ <div class="title"></div>
+ <div class="subtitle">
+ <p>AdonisJs simplicity will make you feel confident about your code</p>
+ <p>
+ Don't know where to start? Read the <a href="https://adonisjs.com/docs">documentation</a>.
+ </p>
+ </div>
+ </section>
+</body>
+</html>
server.js 25(+25 -0)
diff --git a/server.js b/server.js
new file mode 100644
index 0000000..c3a987b
--- /dev/null
+++ b/server.js
@@ -0,0 +1,25 @@
+'use strict'
+
+/*
+|--------------------------------------------------------------------------
+| Http server
+|--------------------------------------------------------------------------
+|
+| This file bootstrap Adonisjs to start the HTTP server. You are free to
+| customize the process of booting the http server.
+|
+| """ Loading ace commands """
+| At times you may want to load ace commands when starting the HTTP server.
+| Same can be done by chaining `loadCommands()` method after
+|
+| """ Preloading files """
+| Also you can preload files by calling `preLoad('path/to/file')` method.
+| Make sure to pass relative path from the project root.
+*/
+
+const { Ignitor } = require('@adonisjs/ignitor')
+
+new Ignitor(require('@adonisjs/fold'))
+ .appRoot(__dirname)
+ .fireHttpServer()
+ .catch(console.error)
start/app.js 61(+61 -0)
diff --git a/start/app.js b/start/app.js
new file mode 100644
index 0000000..e42f331
--- /dev/null
+++ b/start/app.js
@@ -0,0 +1,61 @@
+'use strict'
+
+/*
+|--------------------------------------------------------------------------
+| Providers
+|--------------------------------------------------------------------------
+|
+| Providers are building blocks for your Adonis app. Anytime you install
+| a new Adonis specific package, chances are you will register the
+| provider here.
+|
+*/
+const providers = [
+ '@adonisjs/framework/providers/AppProvider',
+ '@adonisjs/framework/providers/ViewProvider',
+ '@adonisjs/lucid/providers/LucidProvider',
+ '@adonisjs/bodyparser/providers/BodyParserProvider',
+ '@adonisjs/cors/providers/CorsProvider',
+ '@adonisjs/shield/providers/ShieldProvider',
+ '@adonisjs/session/providers/SessionProvider',
+ '@adonisjs/auth/providers/AuthProvider'
+]
+
+/*
+|--------------------------------------------------------------------------
+| Ace Providers
+|--------------------------------------------------------------------------
+|
+| Ace providers are required only when running ace commands. For example
+| Providers for migrations, tests etc.
+|
+*/
+const aceProviders = [
+ '@adonisjs/lucid/providers/MigrationsProvider'
+]
+
+/*
+|--------------------------------------------------------------------------
+| Aliases
+|--------------------------------------------------------------------------
+|
+| Aliases are short unique names for IoC container bindings. You are free
+| to create your own aliases.
+|
+| For example:
+| { Route: 'Adonis/Src/Route' }
+|
+*/
+const aliases = {}
+
+/*
+|--------------------------------------------------------------------------
+| Commands
+|--------------------------------------------------------------------------
+|
+| Here you store ace commands for your package
+|
+*/
+const commands = []
+
+module.exports = { providers, aceProviders, aliases, commands }
start/kernel.js 63(+63 -0)
diff --git a/start/kernel.js b/start/kernel.js
new file mode 100644
index 0000000..b4f2720
--- /dev/null
+++ b/start/kernel.js
@@ -0,0 +1,63 @@
+'use strict'
+
+/** @type {import('@adonisjs/framework/src/Server')} */
+const Server = use('Server')
+
+/*
+|--------------------------------------------------------------------------
+| Global Middleware
+|--------------------------------------------------------------------------
+|
+| Global middleware are executed on each http request only when the routes
+| match.
+|
+*/
+const globalMiddleware = [
+ 'Adonis/Middleware/BodyParser',
+ 'Adonis/Middleware/Session',
+ 'Adonis/Middleware/Shield',
+ 'Adonis/Middleware/AuthInit',
+ 'App/Middleware/ConvertEmptyStringsToNull',
+]
+
+/*
+|--------------------------------------------------------------------------
+| Named Middleware
+|--------------------------------------------------------------------------
+|
+| Named middleware is key/value object to conditionally add middleware on
+| specific routes or group of routes.
+|
+| // define
+| {
+| auth: 'Adonis/Middleware/Auth'
+| }
+|
+| // use
+| Route.get().middleware('auth')
+|
+*/
+const namedMiddleware = {
+ auth: 'Adonis/Middleware/Auth',
+ guest: 'Adonis/Middleware/AllowGuestOnly'
+}
+
+/*
+|--------------------------------------------------------------------------
+| Server Middleware
+|--------------------------------------------------------------------------
+|
+| Server level middleware are executed even when route for a given URL is
+| not registered. Features like `static assets` and `cors` needs better
+| control over request lifecycle.
+|
+*/
+const serverMiddleware = [
+ 'Adonis/Middleware/Static',
+ 'Adonis/Middleware/Cors'
+]
+
+Server
+ .registerGlobal(globalMiddleware)
+ .registerNamed(namedMiddleware)
+ .use(serverMiddleware)
start/routes.js 20(+20 -0)
diff --git a/start/routes.js b/start/routes.js
new file mode 100644
index 0000000..c6ad938
--- /dev/null
+++ b/start/routes.js
@@ -0,0 +1,20 @@
+'use strict'
+
+/*
+|--------------------------------------------------------------------------
+| Routes
+|--------------------------------------------------------------------------
+|
+| Http routes are entry points to your web application. You can create
+| routes for different URL's and bind Controller actions to them.
+|
+| A complete guide on routing is available here.
+| http://adonisjs.com/docs/4.1/routing
+|
+*/
+
+/** @type {typeof import('@adonisjs/framework/src/Route/Manager')} */
+const Route = use('Route')
+
+// Main routes
+Route.on('/').render('index')
\ No newline at end of file