0.6.9 • Published 11 months ago

obotix v0.6.9

Weekly downloads
-
License
MIT
Repository
-
Last release
11 months 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

11 months ago

0.6.6

11 months ago

0.6.9

11 months ago

0.6.8

11 months ago

0.6.3

11 months ago

0.6.2

11 months ago

0.6.4

11 months ago

0.6.1

11 months ago

0.6.0

1 year ago

0.5.10

1 year ago

0.5.11

1 year ago

0.4.9

1 year ago

0.4.8

1 year ago

0.5.12

1 year ago

0.3.0

1 year ago

0.5.4

1 year ago

0.3.6

1 year ago

0.5.3

1 year ago

0.3.5

1 year ago

0.5.6

1 year ago

0.3.8

1 year ago

0.5.5

1 year ago

0.3.7

1 year ago

0.5.0

1 year ago

0.3.2

1 year ago

0.3.1

1 year ago

0.5.2

1 year ago

0.3.4

1 year ago

0.5.1

1 year ago

0.3.3

1 year ago

0.5.8

1 year ago

0.5.7

1 year ago

0.3.9

1 year ago

0.5.9

1 year ago

0.3.16

1 year ago

0.3.15

1 year ago

0.3.14

1 year ago

0.3.13

1 year ago

0.3.12

1 year ago

0.3.11

1 year ago

0.3.10

1 year ago

0.4.10

1 year ago

0.4.11

1 year ago

0.4.5

1 year ago

0.4.7

1 year ago

0.4.6

1 year ago

0.4.1

1 year ago

0.4.0

1 year ago

0.4.2

1 year ago

0.2.10

2 years ago

0.2.7

2 years ago

0.2.6

2 years ago

0.2.9

2 years ago

0.2.8

2 years ago

0.2.3

2 years ago

0.2.5

2 years ago

0.2.4

2 years ago

0.2.2

2 years ago

0.2.1

2 years ago

0.1.0

2 years ago