0.6.9 • Published 2 years ago

obotix v0.6.9

Weekly downloads
-
License
MIT
Repository
-
Last release
2 years ago

obotix - in ALPHA

Installation

npm i obotix

Install with scaffold

npm i -g obotix-cli
obotix-cli create backend my-project
cd my-project
npm i 
# create .env from env.ini
npm run dev

Getting Started - index Example

// import obotix app
import obotix from 'obotix'
// create a custom route
import customRoute from './routes/custom.js'

// initialize the system, logger, and app
await obotix.init()
const log = obotix.getLogger('app:index')
const app = mytn.getApp()

// get an obotix model if needed
const usersModel = obotix.getModel('users')
const configMode = obotix.getModel('config')
const configMode = obotix.getModel('apikey')

// get direct access to core objects if needed
const monoogse = obotix.getMongoose()
const express = obotix.getExpress()

// add custom routes
app.use('/v1', customRoute( obotix.getRouter() ) )

// start listening for requests
obotix.listen( () => {
    log.info(`Service is listening on port ${process.env.OAPI_PORT}.`)
})

Create Route - Example

import obotix from 'obotix'
import CustomController from '../controllers/custom.js'

export default function (router) {

    // for singleton Controller use "new CustomController()" otherwise
    const customController = CustomController() 

    const rateLimit = obotix.getMiddleware('rateLimit')

    router.get('/custom', rateLimit, async (res, req) => {
       try {
            const response = await customController.get(req, res)
            if (response.data !== undefined && response.status === 200) 
                res.status(response.status).json(response.data)
            else 
                res.status(response.status).json(response)
        } catch(ex) {
            // allow internal error middleware to handle
            throw new Error(ex.message)
        }
    })

    return router
}

Create Controller - Example

import obotix from 'obotix'
import dbCollecttion from '../models/custom.js'

class CustomController extends baseClass.ObotixController {
    constructor() {
        super('ctrl:custom')
        this.dbconn = dbCollecttion()
    }

    async get(req, res) {
        var response = { status: 200, message: 'OK' }
        const query = super.get(req, res)
        const paginate = this.paginate(req)
        const projection = { 
            __v: 0
        }

        try {
            response.data = await this.dbconn.model.find(query, projection).limit(paginate.limit).skip(paginate.page).exec()
            if (response.field === 'notExpected') {
                response.status = 400
                response.message = 'Something is not right'
                delete response.data // if you don't want to return the document
            }
        } catch (ex) {
            this.log.error(ex.message, { stack: ex.stack })
            throw new Error(ex.message) 
        }

        return response
    }
}

// Singleton approach - otherwise just export the class
var customController = undefined
export default function () {
    if (customController === undefined) customController = new CustomController()
    return customController
}

Create Model - Example

import obotix from 'obotix'

var dbconn = undefined

export default function () {

    // singleton - avoids compiling schema more than once
    if (dbconn !== undefined) return dbconn

    const log = obotix.getLogger('model:custom')

    dbconn = {
        connection: undefined,
        schema: undefined,
        model: undefined
    }

    // generic schema without strict definition or integrity 
    // https://mongoosejs.com/docs/guide.html to define a proper schema with integrity
    try {
        dbconn.connection = obotix.db.getConnFromConnStr(process.env.OAPI_DB_NODE) 
        dbconn.schema = new obotix.db.mongoose.Schema({ any: db.mongoose.Schema.Types.Mixed }, { strict: false })
        dbconn.model = dbconn.connection.model('Custom', dbconn.schema)
    } catch(ex) {
        // reset dbconn, log errors, and raise an exception
        dbconn = undefined
        this.log.error(ex.message, { stack: ex.stack })
        throw new Error(ex.message) 
    }

    return dbconn
}

Rate Limit

Rate limiter is added to specific routes that deal with heavy processing, such as DB or IO. rateLimit is param middleware.

import obotix from 'obotix'
const rateLimit = obotix.getMiddleware('rateLimit')

router.post('/', rateLimit, async (req, res) => {
    // read write DB
}

ApiKey

Auth is added to specific routes that require it. auth is param middleware.

import obotix from 'obotix'
const rateLimit = obotix.getMiddleware('rateLimit')
const apikey = obotix.getMiddleware('apiKey')

router.put('/', rateLimit, apikey, async (req, res) => {

    console.log( req.apiuser.username )
    console.log( req.apiuser.apikey )
    console.log( req.apiuser.role )
    console.log( req.apiuser.expiery )

    // execute auth required code
    // read write DB
}

Roles

Roles is added to specific routes that require it. Roles is param middleware.

import obotix from 'obotix'
const rateLimit = obotix.getMiddleware('rateLimit')
const apikey = obotix.getMiddleware('apiKey')
const role = obotix.getMiddleware('role')
const roles = obotix.getConfig().roles

router.get('/', rateLimit, apikey, role(roles.manager), async (req, res) => {
    // execute role privileged colde
    // execute auth required code
    // read write DB
}

Express Request Object for Auth

// Once Auth has been executed, it will store the verification object in the request.
// The following represents the object and it's condition.

 function (req, res) {
    console.log ( req.authuser )
    console.log ( req.authuser._id_ )       // id is either of User or Apikey
    console.log ( req.authuser.username )
    console.log ( req.authuser.role )
    console.log ( req.authuser.email )      // only if auth is NOT an ApiKey
 }

Events

//  List of avilable events.
//
// - `onAccountCreate` - Emitted when a new user successfully registers a new account.
// - `onAccountDelete` - Emitted when a user deletes their account.
// - `onAccountLogin` - Emitted when user successfully login.
// - `onAccountLogout` - Emitted when user successfully logout.
// - `onConfigChange` - Emitted when application recieves a config change update.


    import obotix from 'obotix'

    obotix.onEvent('onAccountCreate', (userDoc) => {
        // code stuff
    })

    obotix.onEvent('onConfigChange', (configDoc) => {
        // code stuff
    })

Response Codes

200 OK - Request success and result found
204 No Content - Request success, but NOT successful results 
301 Moved Permanently - Route moved, send new route
400 Bad Request - Invalid request data sent (Bad data)
401 Unauthorized - No auth or invalid authentication (No credentials)
403 Forbidden - Invalidation authorization (Not enough privileges)
404 Not Found - Non existent ws request (no such endpoint - bad URI)
429 Too Many Requests - Returns too many requests from same IP (Rate-Limiting)
500 Inter Server Error - Server side errors and issues
503 Service Unavailable - In maintenance mode or overloaded

Firebase

Custom Auth

Admin SDK

Website Auth

firebase-adminskd.gpg

  • decrypt | gpg --pinentry-mode=loopback --passphrase ADMIN-TOKEN_passphrase -d --no-use-agent -o .env .env.gpg
  • encrypt | gpg --pinentry-mode=loopback --passphrase ADMIN-TOKEN_passphrase -c .env
0.6.7

2 years ago

0.6.6

2 years ago

0.6.9

2 years ago

0.6.8

2 years ago

0.6.3

2 years ago

0.6.2

2 years ago

0.6.4

2 years ago

0.6.1

2 years ago

0.6.0

2 years ago

0.5.10

2 years ago

0.5.11

2 years ago

0.4.9

2 years ago

0.4.8

2 years ago

0.5.12

2 years ago

0.3.0

2 years ago

0.5.4

2 years ago

0.3.6

2 years ago

0.5.3

2 years ago

0.3.5

2 years ago

0.5.6

2 years ago

0.3.8

2 years ago

0.5.5

2 years ago

0.3.7

2 years ago

0.5.0

2 years ago

0.3.2

2 years ago

0.3.1

2 years ago

0.5.2

2 years ago

0.3.4

2 years ago

0.5.1

2 years ago

0.3.3

2 years ago

0.5.8

2 years ago

0.5.7

2 years ago

0.3.9

2 years ago

0.5.9

2 years ago

0.3.16

2 years ago

0.3.15

2 years ago

0.3.14

2 years ago

0.3.13

2 years ago

0.3.12

2 years ago

0.3.11

2 years ago

0.3.10

2 years ago

0.4.10

2 years ago

0.4.11

2 years ago

0.4.5

2 years ago

0.4.7

2 years ago

0.4.6

2 years ago

0.4.1

2 years ago

0.4.0

2 years ago

0.4.2

2 years ago

0.2.10

3 years ago

0.2.7

3 years ago

0.2.6

3 years ago

0.2.9

3 years ago

0.2.8

3 years ago

0.2.3

3 years ago

0.2.5

3 years ago

0.2.4

3 years ago

0.2.2

3 years ago

0.2.1

3 years ago

0.1.0

3 years ago