Skip to content

Commit

Permalink
session management progress (#2)
Browse files Browse the repository at this point in the history
- feat(session.delete): added
- test(session): add lifecycle tests
- config(session): ttl set to 1 hour
- lib/mysql: DRY
- init-mysql: added 'drop' CLI arg
- ci: custom publish, b/c build test has SQL setup steps
- test(user): remove duplicate setup code
- test(user): add invalid user & pass tests
- doc(README): added install section
- better align object function names with http verbs
  • Loading branch information
msimerson committed Feb 22, 2024
1 parent 7555113 commit 99908d7
Show file tree
Hide file tree
Showing 21 changed files with 366 additions and 224 deletions.
15 changes: 5 additions & 10 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,15 +51,12 @@ jobs:
node-version: ${{ fromJson(needs.get-lts.outputs.active) }}
fail-fast: false
steps:
- name: Start MySQL
run: sudo /etc/init.d/mysql start
- run: sudo /etc/init.d/mysql start
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
name: Node ${{ matrix.node-version }} on ${{ matrix.os }}
with:
node-version: ${{ matrix.node-version }}
- name: Initialize MySQL
run: sh sql/init-mysql.sh
- run: sh sql/init-mysql.sh
- run: npm install
- run: npm test

Expand All @@ -81,8 +78,7 @@ jobs:
name: Node ${{ matrix.node-version }} on ${{ matrix.os }}
with:
node-version: ${{ matrix.node-version }}
- name: Initialize MySQL
run: sh sql/init-mysql.sh
- run: sh sql/init-mysql.sh
- run: npm install
- run: npm test

Expand All @@ -101,10 +97,9 @@ jobs:
choco install mysql
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
name: Node ${{ matrix.node-version }} on ${{ matrix.os }}
name: Node ${{ matrix.node-version }}
with:
node-version: ${{ matrix.node-version }}
- name: Initialize MySQL
run: sh sql/init-mysql.sh
- run: sh sql/init-mysql.sh
- run: npm install
- run: npm test
53 changes: 50 additions & 3 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,53 @@ env:
CI: true

jobs:
publish:
uses: NicTool/.github/.github/workflows/publish.yml@main
secrets: inherit
build:
runs-on: ubuntu-latest
steps:
- run: sudo /etc/init.d/mysql start
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
- run: sh sql/init-mysql.sh
- run: npm install
- run: npm test

publish-npm:
needs: build
runs-on: ubuntu-latest
steps:
- uses: actions/setup-node@v4
name: Node ${{ env.node-version }}
with:
node-version: ${{ env.node-version }}
registry-url: https://registry.npmjs.org/

- uses: actions/checkout@v4
with:
fetch-depth: 0
# fetch-depth 0 needed by GitHub Release

- name: publish to NPM
run: npm publish --access=public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }}

- name: GitHub Release
uses: justincy/[email protected]
id: release

publish-gpr:
needs: build
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ env.node-version }}
registry-url: https://npm.pkg.github.com/
scope: '@nictool'
- run: npm publish
env:
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
30 changes: 29 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,34 @@

# nt-api

nictool api
nictool api v3


## Install

1. Install [Node.js](https://nodejs.org/en/download/) on your system
2. Download the NicTool v3 API


```
git clone https://github.com/NicTool/api.git nictool-api
cd nictool-api
npm install
```

## Configure

Edit the files in conf.d to reflect your local settings. Each config file has a default section which lists all available config settings. Below the `default` section are optional deployment environments such as `production`, `development`, and `test`. When a config file is loaded, the environment variable `NODE_ENV` is checked and if defined, any overrides in the matching deployment section are applied.

## Start the service

Running one of these commands:

`npm run start (production)`

or

`npm run develop (development)`

will start up the HTTP service on the port specified in conf.d/http.yml.

5 changes: 4 additions & 1 deletion conf.d/mysql.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@

# default settings apply to EVERY deployment
default:
host: 127.0.0.1
port: 3306
Expand All @@ -10,14 +10,17 @@ default:
- TIMESTAMP
decimalNumbers: true

# settings below this line override default settings
production:
host: mysql
password: "********"

# used for CI testing (GitHub Actions workflows)
test:
user: root
password: root

# used by code coverage testing
cov:
user: root
password: root
Expand Down
7 changes: 4 additions & 3 deletions conf.d/session.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,16 @@ default:
# https://hapi.dev/module/cookie/api/?v=12.0.1
name: sid-nictool
password: af1b926a5e21f535c4f5b6c42941c4cf
# ttl:
ttl: 3600000 # 1 hour
# domain:
path: /
# clearInvalid: false
clearInvalid: true
isSameSite: Strict
isSecure: true
isHttpOnly: true
keepAlive: false
# redirectTo:
# group: NicTool

production:
cookie:
Expand All @@ -27,4 +28,4 @@ test:
development:
cookie:
isSecure: false
password: ^NicTool.Is,The#Best_Dns-Manager$
password: ^NicTool.Is,The#Best_Dns-Manager$
7 changes: 3 additions & 4 deletions lib/group.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,10 @@ 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 })
const g = await this.get({ nt_group_id: args.nt_group_id })
if (g.length) {
// console.log(g)
return g[0].nt_group_id
Expand All @@ -20,12 +19,12 @@ class Group {
return groupId
}

async read(args) {
async get(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 })
const g = await this.get({ 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=?`, [
Expand Down
42 changes: 9 additions & 33 deletions lib/mysql.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,24 +14,24 @@ class MySQL {
// if (this.dbh && this.dbh?.connection?.connectionId) return this.dbh;

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

this.dbh = await mysql.createConnection(cfg)
if (config.debug)
if (this._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`)
if (this._debug) console.log(`(re)connecting to MySQL`)
this.dbh = await this.connect()
}

// console.log(query)
// console.log(paramsArray)
if (this._debug) console.log(query)
if (this._debug) console.log(paramsArray)
const [rows, fields] = await this.dbh.execute(query, paramsArray)
if (this.debug()) {
if (this._debug) {
if (fields) console.log(fields)
console.log(rows)
}
Expand All @@ -42,30 +42,11 @@ class MySQL {
}

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
return await this.execute(query, Object.values(params))
}

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]
Expand All @@ -80,17 +61,12 @@ class MySQL {
}
}

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

async disconnect(dbh) {
const d = dbh || this.dbh
if (config.debug)
if (this._debug)
console.log(`MySQL connection id ${d.connection.connectionId}`)
await d.end()
}
Expand Down
32 changes: 17 additions & 15 deletions lib/session.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,40 +4,42 @@ class Session {
constructor() {}

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

const query = `INSERT INTO nt_user_session`

const id = await Mysql.insert(query, {
const id = await Mysql.insert(`INSERT INTO nt_user_session`, {
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) {
async get(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)
for (const f of ['nt_user_session_id', 'nt_user_id', 'nt_user_session']) {
if (args[f] !== undefined) {
query += ` AND s.${f} = ?`
params.push(args[f])
}
}

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

async delete(args) {
const r = await Mysql.execute(
`DELETE FROM nt_user_session WHERE nt_user_session_id=?`,
[args.nt_user_session_id],
)
return r.affectedRows === 1
}
}

module.exports = new Session()
Expand Down
Loading

0 comments on commit 99908d7

Please sign in to comment.