Skip to content

Commit

Permalink
partial user, group, & session
Browse files Browse the repository at this point in the history
  • Loading branch information
msimerson committed Feb 15, 2024
1 parent c049177 commit 5e9306b
Show file tree
Hide file tree
Showing 24 changed files with 1,091 additions and 1 deletion.
8 changes: 8 additions & 0 deletions .eslintrc.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
env:
node: true
es2021: true
extends: eslint:recommended
parserOptions:
ecmaVersion: latest
sourceType: module
rules: {}
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -128,3 +128,5 @@ dist
.yarn/build-state.yml
.yarn/install-state.gz
.pnp.*

package-lock.json
3 changes: 3 additions & 0 deletions .prettierrc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
trailingComma: 'all'
semi: false
singleQuote: true
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
# api
# nt-api

nictool api


21 changes: 21 additions & 0 deletions conf.d/mysql.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@

default:
host: 127.0.0.1
port: 3306
user: nictool
database: nictool
timezone: +00:00
dateStrings:
- DATETIME
- TIMESTAMP
decimalNumbers: true

production:
password: "********"

test:
password: NicToolTesting

development:
password: StaySafeOutThere
socketPath: /opt/local/var/run/mysql57/mysqld.sock
21 changes: 21 additions & 0 deletions conf.d/session.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
default:
secret: nictoolisthebestdnsmanager
name: sessionId
saveUninitialized: false
resave: false
cookie:
httpOnly: false
sameSite: Strict # Strict, Lax, None
path: /
maxAge: 86400000 # 24 hours, in milliseconds

production:
cookie:
secure: true

test:
secret: nictoolisthebestdnsmanager

development:
secret: nictoolisthebestdnsmanager

44 changes: 44 additions & 0 deletions lib/config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
const fs = require('fs/promises')

const YAML = require('yaml')

class config {
constructor(opts = {}) {
this.cfg = {}
this.debug = process.env.NODE_DEBUG ? true : false
this.env = process.env.NODE_ENV ?? opts.env ?? 'development'
if (this.debug) console.log(`debug: true, env: ${this.env}`)
}

async get(name, env) {
const cacheKey = [name, env ?? this.env].join(':')
if (this.cfg?.[cacheKey]) return this.cfg[cacheKey] // cached

const str = await fs.readFile(`./conf.d/${name}.yml`, 'utf8')
const cfg = YAML.parse(str)
// if (this.debug) console.log(cfg)

this.cfg[cacheKey] = applyDefaults(cfg[env ?? this.env], cfg.default)
return this.cfg[cacheKey]
}

getSync(name, env) {
const cacheKey = [name, env ?? this.env].join(':')
if (this.cfg?.[cacheKey]) return this.cfg[cacheKey] // cached

const str = require('fs').readFileSync(`./conf.d/${name}.yml`, 'utf8')
const cfg = YAML.parse(str)

this.cfg[cacheKey] = applyDefaults(cfg[env ?? this.env], cfg.default)
return this.cfg[cacheKey]
}
}

function applyDefaults(cfg = {}, defaults = {}) {
for (const d in defaults) {
if (cfg[d] === undefined) cfg[d] = defaults[d]
}
return cfg
}

module.exports = new config()
40 changes: 40 additions & 0 deletions lib/group.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
const mysql = require('./mysql')

const validate = require('@nictool/nt-validate')

class Group {
constructor() {}

async create(args) {
// console.log(`create`)
const { error } = validate.group.validate(args)
if (error) console.error(error)

const g = await this.read({nt_group_id: args.nt_group_id})
if (g.length) {
// console.log(g)
return g[0].nt_group_id
}

const groupId = await mysql.insert(`INSERT INTO nt_group`, args)
return groupId
}

async read(args) {
return await mysql.select(
`SELECT * FROM nt_group WHERE`,
args,
)
}

async destroy(args) {
const g = await this.read({nt_group_id: args.nt_group_id})
// console.log(g)
if (g.length === 1) {
await mysql.execute(`DELETE FROM nt_group WHERE nt_group_id=?`, [ g[0].nt_group_id ])
}
}
}

module.exports = new Group()
module.exports._mysql = mysql
102 changes: 102 additions & 0 deletions lib/mysql.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
// const crypto = require('crypto')
const mysql = require('mysql2/promise')

const config = require('./config')

class MySQL {
constructor() {
this._debug = config.debug
}

async connect() {
// if (this.dbh && this.dbh?.connection?.connectionId) return this.dbh;

const cfg = await config.get('mysql')
if (config.debug) console.log(cfg)

this.dbh = await mysql.createConnection(cfg)
if (config.debug)
console.log(`MySQL connection id ${this.dbh.connection.connectionId}`)
return this.dbh
}

async execute(query, paramsArray) {
if (!this.dbh || this.dbh?.connection?._closing) {
if (config.debug) console.log(`(re)connecting to MySQL`)
this.dbh = await this.connect()
}

// console.log(query)
// console.log(paramsArray)
const [rows, fields] = await this.dbh.execute(query, paramsArray)
if (this.debug()) {
if (fields) console.log(fields)
console.log(rows)
}

if (/^(REPLACE|INSERT) INTO/.test(query)) return rows.insertId

return rows
}

async insert(query, params = {}) {
if (!this.dbh || this.dbh?.connection?._closing) {
if (config.debug) console.log(`(re)connecting to MySQL`)
this.dbh = await this.connect()
}

query += `(${Object.keys(params).join(',')}) VALUES(${Object.keys(params).map(() => '?')})`

// console.log(query)
// console.log(Object.values(params))
const [rows, fields] = await this.dbh.execute(query, Object.values(params))
if (this.debug()) {
if (fields) console.log(fields)
console.log(rows)
}

return rows.insertId
}

async select(query, params = {}) {
if (!this.dbh || this.dbh?.connection?._closing) {
if (config.debug) console.log(`(re)connecting to MySQL`)
this.dbh = await this.connect()
}

let paramsArray = []
if (Array.isArray(params)) {
paramsArray = [...params]
} else if (typeof params === 'object' && !Array.isArray(params)) {
// Object to SQL. Eg. { id: 'sample' } -> SELECT...WHERE id=?, ['sample']
let first = true
for (const p in params) {
if (!first) query += ' AND'
query += ` ${p}=?`
paramsArray.push(params[p])
first = false
}
}

const [rows, fields] = await this.dbh.execute(query, paramsArray)
if (this.debug()) {
if (fields) console.log(fields)
console.log(rows)
}
return rows
}

async disconnect(dbh) {
const d = dbh || this.dbh
if (config.debug)
console.log(`MySQL connection id ${d.connection.connectionId}`)
await d.end()
}

debug(val) {
if (val !== undefined) this._debug = val
return this._debug
}
}

module.exports = new MySQL()
50 changes: 50 additions & 0 deletions lib/session.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// const crypto = require('crypto')
// const { createHmac, pbkdf2 } = require('node:crypto')

const Mysql = require('./mysql')
// const User = require('./user')

// const validate = require('@nictool/nt-validate')

class Session {
constructor() {}

async create(args) {
const r = await this.read({ nt_user_session: args.nt_user_session })
if (r) return r

const query = `INSERT INTO nt_user_session`

const id = await Mysql.insert(query, {
nt_user_id: args.nt_user_id,
nt_user_session: args.nt_user_session,
last_access: parseInt(Date.now() / 1000, 10),
})

return id
}

async read(args) {
let query = `SELECT s.*
FROM nt_user_session s
LEFT JOIN nt_user u ON s.nt_user_id = u.nt_user_id
WHERE u.deleted=0`

const params = []
if (args.id) {
query += ` AND s.nt_user_session_id = ?`
params.push(args.id)
}
if (args.nt_user_session) {
query += ` AND s.nt_user_session = ?`
params.push(args.nt_user_session)
}

const sessions = await Mysql.execute(query, params)
// console.log(sessions)
return sessions[0]
}
}

module.exports = new Session()
module.exports._mysql = Mysql
Loading

0 comments on commit 5e9306b

Please sign in to comment.