mirror of
https://github.com/Retropex/apolloapi-v2.git
synced 2025-05-29 21:42:30 +02:00
settings api / login api
This commit is contained in:
parent
d8dbe343bd
commit
817cf6fcf9
@ -1,4 +1,4 @@
|
||||
FROM arm32v7/node:8
|
||||
FROM arm32v7/node:9
|
||||
WORKDIR /app
|
||||
RUN npm --version
|
||||
RUN npm install yarn
|
||||
|
@ -5,6 +5,34 @@ exports.up = async function (knex) {
|
||||
table.timestamps(false, true)
|
||||
table.text('password')
|
||||
})
|
||||
|
||||
// settings
|
||||
await knex.schema.createTable('settings', table => {
|
||||
table.increments('id')
|
||||
table.timestamps(false, true)
|
||||
table.enum('miner_mode', ['eco', 'turbo', 'custom']).notNullable()
|
||||
table.float('voltage').notNullable()
|
||||
table.integer('frequency').notNullable()
|
||||
table.integer('fan').notNullable()
|
||||
table.text('connected_wifi')
|
||||
table.boolean('left_sidebar_visibility').notNullable()
|
||||
table.boolean('left_sidebar_extended').notNullable()
|
||||
table.boolean('right_sidebar_visibility').notNullable()
|
||||
table.enum('temperature_unit', ['f', 'c']).notNullable()
|
||||
})
|
||||
|
||||
// default settings
|
||||
await knex('settings').insert({
|
||||
miner_mode: 'eco',
|
||||
voltage: 0.5,
|
||||
frequency: 450,
|
||||
fan: -1,
|
||||
connected_wifi: null,
|
||||
left_sidebar_visibility: true,
|
||||
left_sidebar_extended: true,
|
||||
right_sidebar_visibility: false,
|
||||
temperature_unit: 'f'
|
||||
})
|
||||
}
|
||||
|
||||
exports.down = async function (knex) {
|
||||
|
@ -0,0 +1,26 @@
|
||||
module.exports.typeDefs = `
|
||||
type AuthActions {
|
||||
login (input: AuthLoginInput!): AuthLoginOutput!
|
||||
}
|
||||
|
||||
input AuthLoginInput {
|
||||
password: String!
|
||||
}
|
||||
|
||||
type AuthLoginOutput {
|
||||
result: AuthLoginResult
|
||||
error: Error
|
||||
}
|
||||
|
||||
type AuthLoginResult {
|
||||
accessToken: String!
|
||||
}
|
||||
`
|
||||
|
||||
module.exports.resolvers = {
|
||||
AuthActions: {
|
||||
login (root, args, { dispatch }) {
|
||||
return dispatch('api/auth/login', args.input)
|
||||
}
|
||||
}
|
||||
}
|
@ -13,6 +13,7 @@ module.exports.typeDefs = `
|
||||
}
|
||||
|
||||
type McuStats {
|
||||
timestamp: String!
|
||||
hostname: String,
|
||||
operatingSystem: String
|
||||
uptime: String
|
||||
|
28
src/graphql/graphqlModules/Settings/Settings.js
Normal file
28
src/graphql/graphqlModules/Settings/Settings.js
Normal file
@ -0,0 +1,28 @@
|
||||
module.exports.typeDefs = `
|
||||
type Query {
|
||||
Settings: SettingsActions
|
||||
}
|
||||
|
||||
enum MinerMode { eco, turbo, custom }
|
||||
enum TemperatureUnit { f, c }
|
||||
|
||||
type Settings {
|
||||
minerMode: MinerMode!
|
||||
voltage: Float!,
|
||||
frequency: Int!,
|
||||
fan: Int!
|
||||
connectedWifi: String
|
||||
leftSidebarVisibility: Boolean!
|
||||
leftSidebarExtended: Boolean!
|
||||
rightSidebarVisibility: Boolean!
|
||||
temperatureUnit: TemperatureUnit!
|
||||
}
|
||||
`
|
||||
|
||||
module.exports.resolvers = {
|
||||
Query: {
|
||||
Settings () {
|
||||
return {}
|
||||
}
|
||||
}
|
||||
}
|
13
src/graphql/graphqlModules/Settings/SettingsRead.js
Normal file
13
src/graphql/graphqlModules/Settings/SettingsRead.js
Normal file
@ -0,0 +1,13 @@
|
||||
module.exports.typeDefs = `
|
||||
type SettingsActions {
|
||||
read: SettingsUpdateOutput!
|
||||
}
|
||||
`
|
||||
|
||||
module.exports.resolvers = {
|
||||
SettingsActions: {
|
||||
read (root, args, { dispatch }) {
|
||||
return dispatch('api/settings/read', args.input)
|
||||
}
|
||||
}
|
||||
}
|
34
src/graphql/graphqlModules/Settings/SettingsUpdate.js
Normal file
34
src/graphql/graphqlModules/Settings/SettingsUpdate.js
Normal file
@ -0,0 +1,34 @@
|
||||
module.exports.typeDefs = `
|
||||
type SettingsActions {
|
||||
update (input: SettingsUpdateInput!): SettingsUpdateOutput!
|
||||
}
|
||||
|
||||
input SettingsUpdateInput {
|
||||
minerMode: MinerMode
|
||||
voltage: Float,
|
||||
frequency: Int,
|
||||
fan: Int
|
||||
connectedWifi: String
|
||||
leftSidebarVisibility: Boolean
|
||||
leftSidebarExtended: Boolean
|
||||
rightSidebarVisibility: Boolean
|
||||
temperatureUnit: TemperatureUnit
|
||||
}
|
||||
|
||||
type SettingsUpdateOutput {
|
||||
result: SettingsUpdateResult
|
||||
error: Error
|
||||
}
|
||||
|
||||
type SettingsUpdateResult {
|
||||
settings: Settings!
|
||||
}
|
||||
`
|
||||
|
||||
module.exports.resolvers = {
|
||||
SettingsActions: {
|
||||
update (root, args, { dispatch }) {
|
||||
return dispatch('api/settings/update', args.input)
|
||||
}
|
||||
}
|
||||
}
|
18
src/store/api/auth/authLogin.js
Normal file
18
src/store/api/auth/authLogin.js
Normal file
@ -0,0 +1,18 @@
|
||||
module.exports = ({ define }) => {
|
||||
define('login', async ({ password }, { knex, errors, utils }) => {
|
||||
// TODO transaction
|
||||
const [ setup ] = await knex('setup').select('*').limit(1)
|
||||
if (!setup) {
|
||||
throw new errors.AuthorizationError('Setup not finished')
|
||||
}
|
||||
const isPasswordValid = await utils.auth.comparePassword(password, setup.password)
|
||||
if (!isPasswordValid) {
|
||||
throw new errors.AuthenticationError('Invalid password').addReason({
|
||||
path: 'password',
|
||||
message: 'Invalid password'
|
||||
})
|
||||
}
|
||||
const { accessToken } = utils.auth.generateAccessToken()
|
||||
return { accessToken }
|
||||
})
|
||||
}
|
@ -6,7 +6,7 @@ module.exports = ({ define }) => {
|
||||
throw new errors.AuthorizationError('Setup already done')
|
||||
}
|
||||
await knex('setup').insert({
|
||||
password: utils.hashPassword(password)
|
||||
password: await utils.auth.hashPassword(password)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
@ -3,5 +3,7 @@ const { exec } = require('child_process')
|
||||
module.exports = ({ define }) => {
|
||||
define('reboot', async (payload, { knex, errors, utils }) => {
|
||||
exec('shutdown -r now')
|
||||
}, {
|
||||
auth: true
|
||||
})
|
||||
}
|
||||
|
@ -3,5 +3,7 @@ const { exec } = require('child_process')
|
||||
module.exports = ({ define }) => {
|
||||
define('shutdown', async (payload, { knex, errors, utils }) => {
|
||||
exec('shutdown now')
|
||||
}, {
|
||||
auth: true
|
||||
})
|
||||
}
|
||||
|
@ -4,7 +4,10 @@ const { exec } = require('child_process')
|
||||
module.exports = ({ define }) => {
|
||||
define('stats', async (payload, { knex, errors, utils }) => {
|
||||
const stats = await getOsStats()
|
||||
stats.timestamp = new Date().toISOString()
|
||||
return { stats }
|
||||
}, {
|
||||
auth: true
|
||||
})
|
||||
}
|
||||
|
||||
|
16
src/store/api/settings/collection/settingsRead.js
Normal file
16
src/store/api/settings/collection/settingsRead.js
Normal file
@ -0,0 +1,16 @@
|
||||
module.exports = ({ define }) => {
|
||||
define('read', async (payload, { knex, errors, utils }) => {
|
||||
const [ settings ] = await knex('settings').select([
|
||||
'miner_mode as minerMode',
|
||||
'voltage',
|
||||
'frequency',
|
||||
'fan',
|
||||
'connected_wifi as connectedWifi',
|
||||
'left_sidebar_visibility as leftSidebarVisibility',
|
||||
'left_sidebar_extended as leftSidebarExtended',
|
||||
'right_sidebar_visibility as rightSidebarVisibility',
|
||||
'temperature_unit as temperatureUnit',
|
||||
]).limit(1)
|
||||
return settings
|
||||
})
|
||||
}
|
23
src/store/api/settings/collection/settingsUpdate.js
Normal file
23
src/store/api/settings/collection/settingsUpdate.js
Normal file
@ -0,0 +1,23 @@
|
||||
const updateFields = {
|
||||
minerMode: 'miner_mode',
|
||||
voltage: 'voltage',
|
||||
frequency: 'frequency',
|
||||
fan: 'fan',
|
||||
connectedWifi: 'connected_wifi',
|
||||
leftSidebarVisibility: 'left_sidebar_visibility',
|
||||
leftSidebarExtended: 'left_sidebar_extended',
|
||||
rightSidebarVisibility: 'right_sidebar_visibility',
|
||||
temperatureUnit: 'temperature_unit'
|
||||
}
|
||||
|
||||
module.exports = ({ define }) => {
|
||||
define('update', async (update = {}, { knex, errors, utils }) => {
|
||||
const updateData = {}
|
||||
Object.keys(update).forEach(key => {
|
||||
if (updateFields[key]) {
|
||||
updateData[updateFields[key]] = update[key]
|
||||
}
|
||||
})
|
||||
await knex('settings').update(updateData)
|
||||
})
|
||||
}
|
11
src/store/api/settings/settingsRead.js
Normal file
11
src/store/api/settings/settingsRead.js
Normal file
@ -0,0 +1,11 @@
|
||||
module.exports = ({ define }) => {
|
||||
define('read', async (payload, { dispatch, errors, utils }) => {
|
||||
const settings = await dispatch('api/settings/collection/read')
|
||||
console.log(settings)
|
||||
return {
|
||||
settings
|
||||
}
|
||||
}, {
|
||||
auth: true
|
||||
})
|
||||
}
|
11
src/store/api/settings/settingsUpdate.js
Normal file
11
src/store/api/settings/settingsUpdate.js
Normal file
@ -0,0 +1,11 @@
|
||||
module.exports = ({ define }) => {
|
||||
define('update', async (settings, { dispatch, errors, utils }) => {
|
||||
await dispatch('api/settings/collection/update', settings)
|
||||
const newSettings = await dispatch('api/settings/collection/read')
|
||||
return {
|
||||
settings: newSettings
|
||||
}
|
||||
}, {
|
||||
auth: true
|
||||
})
|
||||
}
|
3
src/test.js
Normal file
3
src/test.js
Normal file
@ -0,0 +1,3 @@
|
||||
const store = require('./store')
|
||||
|
||||
store.dispatch('api/auth/login', { password: 'abcdef' })
|
12
src/utils.js
12
src/utils.js
@ -1,4 +1,6 @@
|
||||
const bcrypt = require('bcryptjs')
|
||||
const jwt = require('jsonwebtoken')
|
||||
const config = require('config')
|
||||
|
||||
module.exports.auth = {
|
||||
hashPassword (password) {
|
||||
@ -10,5 +12,15 @@ module.exports.auth = {
|
||||
return false
|
||||
}
|
||||
return bcrypt.compare(password, hash)
|
||||
},
|
||||
|
||||
generateAccessToken () {
|
||||
const accessToken = jwt.sign({}, config.get('server.secret'), {
|
||||
subject: 'apollouser',
|
||||
audience: 'auth'
|
||||
})
|
||||
return {
|
||||
accessToken
|
||||
}
|
||||
},
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user