diff --git a/package.json b/package.json index 8c304e57..9d53f5dd 100644 --- a/package.json +++ b/package.json @@ -53,6 +53,7 @@ "express": "^4.14.0", "express-oauth-server": "^2.0.0-b1", "moment": "*", + "moniker": "^0.1.2", "morgan": "^1.7.0", "request": "*", "spark-protocol": "../spark-protocol", diff --git a/src/app.js b/src/app.js index 20f933e6..141a57ba 100644 --- a/src/app.js +++ b/src/app.js @@ -81,16 +81,8 @@ export default (settings: Settings, deviceServer: Object): $Application => { settings, ); - // TODO wny do we need next line? (Anton Puko) eventsV1.loadViews(app); api.loadViews(app); - const noRouteMiddleware: Middleware = ( - request: $Request, - response: $Response, - ): mixed => response.sendStatus(404); - - app.use(noRouteMiddleware); - return app; }; diff --git a/src/lib/RouteConfig.js b/src/lib/RouteConfig.js index 691652d3..60abbb49 100644 --- a/src/lib/RouteConfig.js +++ b/src/lib/RouteConfig.js @@ -103,4 +103,8 @@ export default ( }); }); }); + + app.all('*', (request: $Request, response: $Response): void => + response.sendStatus(404), + ); }; diff --git a/src/lib/controllers/Controller.js b/src/lib/controllers/Controller.js index 1e662dda..c8c65b41 100644 --- a/src/lib/controllers/Controller.js +++ b/src/lib/controllers/Controller.js @@ -5,22 +5,16 @@ import type { User } from '../../types'; import type { HttpResult } from './types'; export default class Controller { - user: User; request: $Request; response: $Response; - bad(message: string, status: number = 400) { - return { - data: { - error: message, - ok: false, - }, - status: status, - }; - } + user: User; - bad = (message: string): HttpResult<*> => ({ - data: { message }, - status: 400, + bad = (message: string, status: number = 400): HttpResult<*> => ({ + data: { + error: message, + ok: false, + }, + status, }); ok = (output?: TType): HttpResult => ({ diff --git a/src/lib/controllers/DevicesController__john.js b/src/lib/controllers/DevicesController__john.js index 9ed29ad8..f03beb3a 100644 --- a/src/lib/controllers/DevicesController__john.js +++ b/src/lib/controllers/DevicesController__john.js @@ -1,8 +1,8 @@ // @flow import type { Device, DeviceRepository } from '../../types'; +import type { DeviceAPIType } from '../deviceToAPI'; -import settings from '../../settings'; import Controller from './Controller'; import httpVerb from '../decorators/httpVerb'; import route from '../decorators/route'; @@ -19,11 +19,12 @@ class DevicesController extends Controller { @httpVerb('get') @route('/v1/devices') - async getDevices() { + async getDevices(): Promise<*> { try { const devices = await this._deviceRepository.getAll(); - return this.ok(devices.map(device => deviceToAPI(device))); + return this.ok(devices.map((device: Device): DeviceAPIType => + deviceToAPI(device))); } catch (exception) { // I wish we could return no devices found but meh :/ return this.ok([]); @@ -32,7 +33,7 @@ class DevicesController extends Controller { @httpVerb('get') @route('/v1/devices/:deviceID') - async getDevice(deviceID: string) { + async getDevice(deviceID: string): Promise<*> { try { const device = await this._deviceRepository.getDetailsByID(deviceID); return this.ok(deviceToAPI(device)); @@ -41,13 +42,34 @@ class DevicesController extends Controller { } } + @httpVerb('put') + @route('/v1/devices/:deviceID') + async updateDevice(deviceID: string, postBody: { name?: string }): Promise<*> { + try { + // 1 rename device + if (postBody.name) { + const updatedAttributes = this._deviceRepository.renameDevice( + deviceID, + postBody.name, + ); + + return this.ok({ name: updatedAttributes.name, ok: true }); + } + + + return this.ok(); + } catch (exception) { + return this.bad(exception); + } + } + @httpVerb('post') @route('/v1/devices/:deviceID/:functionName') async callDeviceFunction( deviceID: string, functionName: string, postBody: Object, - ) { + ): Promise<*> { try { const result = await this._deviceRepository.callFunction( deviceID, diff --git a/src/lib/controllers/ProvisioningController.js b/src/lib/controllers/ProvisioningController.js index cc8e8879..3721575e 100644 --- a/src/lib/controllers/ProvisioningController.js +++ b/src/lib/controllers/ProvisioningController.js @@ -1,8 +1,7 @@ // @flow -import type { Device, DeviceRepository } from '../../types'; +import type { DeviceRepository } from '../../types'; -import settings from '../../settings'; import Controller from './Controller'; import httpVerb from '../decorators/httpVerb'; import route from '../decorators/route'; @@ -21,12 +20,12 @@ class ProvisioningController extends Controller { @route('/v1/provisioning/:coreID') async provision( coreID: string, - postBody: {publicKey: string}, - ) { + postBody: { publicKey: string }, + ): Promise<*> { try { const device = await this._deviceRepository.provision( coreID, - 'UserIDGoesHere', + this.user.id, postBody.publicKey, ); diff --git a/src/lib/controllers/types.js b/src/lib/controllers/types.js index 725c2895..e4e2b066 100644 --- a/src/lib/controllers/types.js +++ b/src/lib/controllers/types.js @@ -5,6 +5,9 @@ export type HttpResult = { data: ?TType, status: number, } | { - data: ?string, + data: { + error: string, + ok: false, + }, status: number, }; diff --git a/src/lib/repository/DeviceRepository__john.js b/src/lib/repository/DeviceRepository__john.js index 935d408b..3aaa7b74 100644 --- a/src/lib/repository/DeviceRepository__john.js +++ b/src/lib/repository/DeviceRepository__john.js @@ -24,7 +24,7 @@ class DeviceRepository { this._deviceServer = deviceServer; } - async getByID(deviceID: string): Promise { + getByID = async (deviceID: string): Promise => { const attributes = await this._deviceAttributeRepository.getById(deviceID); const core = this._deviceServer.getCore(attributes.deviceID); // TODO: Not sure if this should actually be the core ID that gets sent @@ -45,33 +45,31 @@ class DeviceRepository { lastFlashedAppName: null, lastHeard: response.lastPing, }; - } + }; - async getDetailsByID(deviceID: string): Promise { + getDetailsByID = async (deviceID: string): Promise => { const core = this._deviceServer.getCore(deviceID); if (!core) { - throw 'Could not get device for ID'; + throw new Error('Could not get device for ID'); } return Promise.all([ this._deviceAttributeRepository.getById(deviceID), core.onApiMessage( - deviceID, - { cmd: "Describe" }, - ) - ]).then(([attributes, description]) => { - return { - ...attributes, - connected: true, - lastFlashedAppName: null, - lastHeard: new Date(), - functions: description.f, - variables: description.v, - }; - }) + deviceID, + { cmd: 'Describe' }, + ), + ]).then(([attributes, description]): Device => ({ + ...attributes, + connected: true, + functions: description.f, + lastFlashedAppName: null, + lastHeard: new Date(), + variables: description.v, + })); + }; - } - async getAll(): Promise> { + getAll = async (): Promise> => { const devicesAttributes = await this._deviceAttributeRepository.getAll(); const devicePromises = devicesAttributes.map(async attributes => { const core = this._deviceServer.getCore(attributes.deviceID); @@ -96,21 +94,21 @@ class DeviceRepository { }); return Promise.all(devicePromises); - } + }; - async callFunction( + callFunction= async ( deviceID: string, functionName: string, functionArguments: Object, - ): Promise<*> { + ): Promise<*> => { const core = this._deviceServer.getCore(deviceID); if (!core) { return null; } - + console.log(functionArguments); const result = await core.onApiMessage( deviceID, - { cmd:'CallFn', name: functionName, args: functionArguments }, + { cmd: 'CallFn', name: functionName, args: functionArguments }, ); if (result.error) { @@ -118,33 +116,33 @@ class DeviceRepository { } return result.result; - } + }; - async provision( + provision = async ( deviceID: string, userID: string, publicKey: string, - ): Promise<*> { - if (!deviceID) { - throw 'No deviceID provided'; - } - - try { - const createdKey = ursa.createPublicKey(publicKey); - if (!publicKey || !ursa.isPublicKey(createdKey)) { - throw 'No key provided'; - } - } catch (exception) { - logger.error('error while parsing publicKey', exception); - throw 'Key error ' + exception; - } + ): Promise<*> => { + if (!deviceID) { + throw new Error('No deviceID provided'); + } + + try { + const createdKey = ursa.createPublicKey(publicKey); + if (!publicKey || !ursa.isPublicKey(createdKey)) { + throw new Error('No key provided'); + } + } catch (exception) { + logger.error('error while parsing publicKey', exception); + throw new Error(`Key error ${exception}`); + } this._deviceKeyRepository.update(deviceID, publicKey); const existingAttributes = this._deviceAttributeRepository.getById( deviceID, ); const attributes = { + deviceID, name: NAME_GENERATOR.choose(), - deviceID: deviceID, ...existingAttributes, registrar: userID, timestamp: new Date(), @@ -152,6 +150,15 @@ class DeviceRepository { this._deviceAttributeRepository.update(attributes); return await this.getByID(deviceID); + }; + + renameDevice = (deviceID: string, name: string): DeviceAttributes => { + const attributes = this._deviceAttributeRepository.getById(deviceID); + const attributesToSave = { + ...attributes, + name, + }; + return this._deviceAttributeRepository.update(attributesToSave); } }