mirror of
https://codeberg.org/timelimit/timelimit-server.git
synced 2025-10-05 19:42:39 +02:00
Send ClientDataStatus after registering new device
This commit is contained in:
parent
41758c32f2
commit
ae044c19d6
20 changed files with 242 additions and 33 deletions
|
@ -16,8 +16,7 @@ On a invalid request body: HTTP status code 400 Bad request
|
||||||
|
|
||||||
On a invalid add device token: HTTP status code 401 Unauthorized
|
On a invalid add device token: HTTP status code 401 Unauthorized
|
||||||
|
|
||||||
On success: a JSON object with the properties ``deviceAuthToken`` and ``ownDeviceId``,
|
On success: object with ``deviceAuthToken`` (string), ``ownDeviceId`` (string) and ``data`` (like a ``/sync/pull-status`` response)
|
||||||
both of the type string
|
|
||||||
|
|
||||||
## POST /child/update-primary-device
|
## POST /child/update-primary-device
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,7 @@ If the mail auth token is invalid/ expired: HTTP status code 401 Unauthorized
|
||||||
|
|
||||||
If there is already a user with the mail address of the mail auth token: HTTP status code 409 Conflict
|
If there is already a user with the mail address of the mail auth token: HTTP status code 409 Conflict
|
||||||
|
|
||||||
On success: object with ``deviceAuthToken`` (string) and ``ownDeviceId`` (string)
|
On success: object with ``deviceAuthToken`` (string), ``ownDeviceId`` (string) and ``data`` (like a ``/sync/pull-status`` response)
|
||||||
|
|
||||||
## POST /parent/sign-in-into-family
|
## POST /parent/sign-in-into-family
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@ On a invalid request body: HTTP status code 400 Bad Request
|
||||||
|
|
||||||
If there is no user with the mail address of the mail auth token: HTTP status code 409 Conflict
|
If there is no user with the mail address of the mail auth token: HTTP status code 409 Conflict
|
||||||
|
|
||||||
On success: object with ``deviceAuthToken`` (string) and ``ownDeviceId`` (string)
|
On success: object with ``deviceAuthToken`` (string), ``ownDeviceId`` (string) and ``data`` (like a ``/sync/pull-status`` response)
|
||||||
|
|
||||||
## POST /parent/can-recover-password
|
## POST /parent/can-recover-password
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,9 @@
|
||||||
},
|
},
|
||||||
"parentName": {
|
"parentName": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
|
},
|
||||||
|
"clientLevel": {
|
||||||
|
"type": "number"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"additionalProperties": false,
|
"additionalProperties": false,
|
||||||
|
|
|
@ -9,6 +9,9 @@
|
||||||
},
|
},
|
||||||
"deviceName": {
|
"deviceName": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
|
},
|
||||||
|
"clientLevel": {
|
||||||
|
"type": "number"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"additionalProperties": false,
|
"additionalProperties": false,
|
||||||
|
|
|
@ -9,6 +9,9 @@
|
||||||
},
|
},
|
||||||
"deviceName": {
|
"deviceName": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
|
},
|
||||||
|
"clientLevel": {
|
||||||
|
"type": "number"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"additionalProperties": false,
|
"additionalProperties": false,
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
# Untitled number in CreateFamilyByMailTokenRequest Schema
|
||||||
|
|
||||||
|
```txt
|
||||||
|
https://timelimit.io/CreateFamilyByMailTokenRequest#/properties/clientLevel
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
| Abstract | Extensible | Status | Identifiable | Custom Properties | Additional Properties | Access Restrictions | Defined In |
|
||||||
|
| :------------------ | :--------- | :------------- | :---------------------- | :---------------- | :-------------------- | :------------------ | :---------------------------------------------------------------------------------------------------------------- |
|
||||||
|
| Can be instantiated | No | Unknown status | Unknown identifiability | Forbidden | Allowed | none | [CreateFamilyByMailTokenRequest.schema.json\*](CreateFamilyByMailTokenRequest.schema.json "open original schema") |
|
||||||
|
|
||||||
|
## clientLevel Type
|
||||||
|
|
||||||
|
`number`
|
|
@ -24,6 +24,7 @@ https://timelimit.io/CreateFamilyByMailTokenRequest
|
||||||
| [deviceName](#devicename) | `string` | Required | cannot be null | [CreateFamilyByMailTokenRequest](createfamilybymailtokenrequest-properties-devicename.md "https://timelimit.io/CreateFamilyByMailTokenRequest#/properties/deviceName") |
|
| [deviceName](#devicename) | `string` | Required | cannot be null | [CreateFamilyByMailTokenRequest](createfamilybymailtokenrequest-properties-devicename.md "https://timelimit.io/CreateFamilyByMailTokenRequest#/properties/deviceName") |
|
||||||
| [timeZone](#timezone) | `string` | Required | cannot be null | [CreateFamilyByMailTokenRequest](createfamilybymailtokenrequest-properties-timezone.md "https://timelimit.io/CreateFamilyByMailTokenRequest#/properties/timeZone") |
|
| [timeZone](#timezone) | `string` | Required | cannot be null | [CreateFamilyByMailTokenRequest](createfamilybymailtokenrequest-properties-timezone.md "https://timelimit.io/CreateFamilyByMailTokenRequest#/properties/timeZone") |
|
||||||
| [parentName](#parentname) | `string` | Required | cannot be null | [CreateFamilyByMailTokenRequest](createfamilybymailtokenrequest-properties-parentname.md "https://timelimit.io/CreateFamilyByMailTokenRequest#/properties/parentName") |
|
| [parentName](#parentname) | `string` | Required | cannot be null | [CreateFamilyByMailTokenRequest](createfamilybymailtokenrequest-properties-parentname.md "https://timelimit.io/CreateFamilyByMailTokenRequest#/properties/parentName") |
|
||||||
|
| [clientLevel](#clientlevel) | `number` | Optional | cannot be null | [CreateFamilyByMailTokenRequest](createfamilybymailtokenrequest-properties-clientlevel.md "https://timelimit.io/CreateFamilyByMailTokenRequest#/properties/clientLevel") |
|
||||||
|
|
||||||
## mailAuthToken
|
## mailAuthToken
|
||||||
|
|
||||||
|
@ -133,6 +134,24 @@ https://timelimit.io/CreateFamilyByMailTokenRequest
|
||||||
|
|
||||||
`string`
|
`string`
|
||||||
|
|
||||||
|
## clientLevel
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
`clientLevel`
|
||||||
|
|
||||||
|
* is optional
|
||||||
|
|
||||||
|
* Type: `number`
|
||||||
|
|
||||||
|
* cannot be null
|
||||||
|
|
||||||
|
* defined in: [CreateFamilyByMailTokenRequest](createfamilybymailtokenrequest-properties-clientlevel.md "https://timelimit.io/CreateFamilyByMailTokenRequest#/properties/clientLevel")
|
||||||
|
|
||||||
|
### clientLevel Type
|
||||||
|
|
||||||
|
`number`
|
||||||
|
|
||||||
# CreateFamilyByMailTokenRequest Definitions
|
# CreateFamilyByMailTokenRequest Definitions
|
||||||
|
|
||||||
## Definitions group PlaintextParentPassword
|
## Definitions group PlaintextParentPassword
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
# Untitled number in RegisterChildDeviceRequest Schema
|
||||||
|
|
||||||
|
```txt
|
||||||
|
https://timelimit.io/RegisterChildDeviceRequest#/properties/clientLevel
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
| Abstract | Extensible | Status | Identifiable | Custom Properties | Additional Properties | Access Restrictions | Defined In |
|
||||||
|
| :------------------ | :--------- | :------------- | :---------------------- | :---------------- | :-------------------- | :------------------ | :-------------------------------------------------------------------------------------------------------- |
|
||||||
|
| Can be instantiated | No | Unknown status | Unknown identifiability | Forbidden | Allowed | none | [RegisterChildDeviceRequest.schema.json\*](RegisterChildDeviceRequest.schema.json "open original schema") |
|
||||||
|
|
||||||
|
## clientLevel Type
|
||||||
|
|
||||||
|
`number`
|
|
@ -21,6 +21,7 @@ https://timelimit.io/RegisterChildDeviceRequest
|
||||||
| [registerToken](#registertoken) | `string` | Required | cannot be null | [RegisterChildDeviceRequest](registerchilddevicerequest-properties-registertoken.md "https://timelimit.io/RegisterChildDeviceRequest#/properties/registerToken") |
|
| [registerToken](#registertoken) | `string` | Required | cannot be null | [RegisterChildDeviceRequest](registerchilddevicerequest-properties-registertoken.md "https://timelimit.io/RegisterChildDeviceRequest#/properties/registerToken") |
|
||||||
| [childDevice](#childdevice) | `object` | Required | cannot be null | [RegisterChildDeviceRequest](registerchilddevicerequest-definitions-newdeviceinfo.md "https://timelimit.io/RegisterChildDeviceRequest#/properties/childDevice") |
|
| [childDevice](#childdevice) | `object` | Required | cannot be null | [RegisterChildDeviceRequest](registerchilddevicerequest-definitions-newdeviceinfo.md "https://timelimit.io/RegisterChildDeviceRequest#/properties/childDevice") |
|
||||||
| [deviceName](#devicename) | `string` | Required | cannot be null | [RegisterChildDeviceRequest](registerchilddevicerequest-properties-devicename.md "https://timelimit.io/RegisterChildDeviceRequest#/properties/deviceName") |
|
| [deviceName](#devicename) | `string` | Required | cannot be null | [RegisterChildDeviceRequest](registerchilddevicerequest-properties-devicename.md "https://timelimit.io/RegisterChildDeviceRequest#/properties/deviceName") |
|
||||||
|
| [clientLevel](#clientlevel) | `number` | Optional | cannot be null | [RegisterChildDeviceRequest](registerchilddevicerequest-properties-clientlevel.md "https://timelimit.io/RegisterChildDeviceRequest#/properties/clientLevel") |
|
||||||
|
|
||||||
## registerToken
|
## registerToken
|
||||||
|
|
||||||
|
@ -76,6 +77,24 @@ https://timelimit.io/RegisterChildDeviceRequest
|
||||||
|
|
||||||
`string`
|
`string`
|
||||||
|
|
||||||
|
## clientLevel
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
`clientLevel`
|
||||||
|
|
||||||
|
* is optional
|
||||||
|
|
||||||
|
* Type: `number`
|
||||||
|
|
||||||
|
* cannot be null
|
||||||
|
|
||||||
|
* defined in: [RegisterChildDeviceRequest](registerchilddevicerequest-properties-clientlevel.md "https://timelimit.io/RegisterChildDeviceRequest#/properties/clientLevel")
|
||||||
|
|
||||||
|
### clientLevel Type
|
||||||
|
|
||||||
|
`number`
|
||||||
|
|
||||||
# RegisterChildDeviceRequest Definitions
|
# RegisterChildDeviceRequest Definitions
|
||||||
|
|
||||||
## Definitions group NewDeviceInfo
|
## Definitions group NewDeviceInfo
|
||||||
|
|
15
docs/schema/signintofamilyrequest-properties-clientlevel.md
Normal file
15
docs/schema/signintofamilyrequest-properties-clientlevel.md
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
# Untitled number in SignIntoFamilyRequest Schema
|
||||||
|
|
||||||
|
```txt
|
||||||
|
https://timelimit.io/SignIntoFamilyRequest#/properties/clientLevel
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
| Abstract | Extensible | Status | Identifiable | Custom Properties | Additional Properties | Access Restrictions | Defined In |
|
||||||
|
| :------------------ | :--------- | :------------- | :---------------------- | :---------------- | :-------------------- | :------------------ | :---------------------------------------------------------------------------------------------- |
|
||||||
|
| Can be instantiated | No | Unknown status | Unknown identifiability | Forbidden | Allowed | none | [SignIntoFamilyRequest.schema.json\*](SignIntoFamilyRequest.schema.json "open original schema") |
|
||||||
|
|
||||||
|
## clientLevel Type
|
||||||
|
|
||||||
|
`number`
|
|
@ -21,6 +21,7 @@ https://timelimit.io/SignIntoFamilyRequest
|
||||||
| [mailAuthToken](#mailauthtoken) | `string` | Required | cannot be null | [SignIntoFamilyRequest](signintofamilyrequest-properties-mailauthtoken.md "https://timelimit.io/SignIntoFamilyRequest#/properties/mailAuthToken") |
|
| [mailAuthToken](#mailauthtoken) | `string` | Required | cannot be null | [SignIntoFamilyRequest](signintofamilyrequest-properties-mailauthtoken.md "https://timelimit.io/SignIntoFamilyRequest#/properties/mailAuthToken") |
|
||||||
| [parentDevice](#parentdevice) | `object` | Required | cannot be null | [SignIntoFamilyRequest](signintofamilyrequest-definitions-newdeviceinfo.md "https://timelimit.io/SignIntoFamilyRequest#/properties/parentDevice") |
|
| [parentDevice](#parentdevice) | `object` | Required | cannot be null | [SignIntoFamilyRequest](signintofamilyrequest-definitions-newdeviceinfo.md "https://timelimit.io/SignIntoFamilyRequest#/properties/parentDevice") |
|
||||||
| [deviceName](#devicename) | `string` | Required | cannot be null | [SignIntoFamilyRequest](signintofamilyrequest-properties-devicename.md "https://timelimit.io/SignIntoFamilyRequest#/properties/deviceName") |
|
| [deviceName](#devicename) | `string` | Required | cannot be null | [SignIntoFamilyRequest](signintofamilyrequest-properties-devicename.md "https://timelimit.io/SignIntoFamilyRequest#/properties/deviceName") |
|
||||||
|
| [clientLevel](#clientlevel) | `number` | Optional | cannot be null | [SignIntoFamilyRequest](signintofamilyrequest-properties-clientlevel.md "https://timelimit.io/SignIntoFamilyRequest#/properties/clientLevel") |
|
||||||
|
|
||||||
## mailAuthToken
|
## mailAuthToken
|
||||||
|
|
||||||
|
@ -76,6 +77,24 @@ https://timelimit.io/SignIntoFamilyRequest
|
||||||
|
|
||||||
`string`
|
`string`
|
||||||
|
|
||||||
|
## clientLevel
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
`clientLevel`
|
||||||
|
|
||||||
|
* is optional
|
||||||
|
|
||||||
|
* Type: `number`
|
||||||
|
|
||||||
|
* cannot be null
|
||||||
|
|
||||||
|
* defined in: [SignIntoFamilyRequest](signintofamilyrequest-properties-clientlevel.md "https://timelimit.io/SignIntoFamilyRequest#/properties/clientLevel")
|
||||||
|
|
||||||
|
### clientLevel Type
|
||||||
|
|
||||||
|
`number`
|
||||||
|
|
||||||
# SignIntoFamilyRequest Definitions
|
# SignIntoFamilyRequest Definitions
|
||||||
|
|
||||||
## Definitions group NewDeviceInfo
|
## Definitions group NewDeviceInfo
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* server component for the TimeLimit App
|
* server component for the TimeLimit App
|
||||||
* Copyright (C) 2019 Jonas Lochmann
|
* Copyright (C) 2019 - 2022 Jonas Lochmann
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Affero General Public License as
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
@ -24,10 +24,12 @@ import { logoutAtPrimaryDevice } from '../function/child/logout-at-primary-devic
|
||||||
import { setPrimaryDevice } from '../function/child/set-primary-device'
|
import { setPrimaryDevice } from '../function/child/set-primary-device'
|
||||||
import { WebsocketApi } from '../websocket'
|
import { WebsocketApi } from '../websocket'
|
||||||
import { isRegisterChildDeviceRequest, isRequestWithAuthToken, isUpdatePrimaryDeviceRequest } from './validator'
|
import { isRegisterChildDeviceRequest, isRequestWithAuthToken, isUpdatePrimaryDeviceRequest } from './validator'
|
||||||
|
import { EventHandler } from '../monitoring/eventhandler'
|
||||||
|
|
||||||
export const createChildRouter = ({ database, websocket }: {
|
export const createChildRouter = ({ database, websocket, eventHandler }: {
|
||||||
database: Database,
|
database: Database
|
||||||
websocket: WebsocketApi
|
websocket: WebsocketApi
|
||||||
|
eventHandler: EventHandler
|
||||||
}) => {
|
}) => {
|
||||||
const router = Router()
|
const router = Router()
|
||||||
|
|
||||||
|
@ -37,15 +39,17 @@ export const createChildRouter = ({ database, websocket }: {
|
||||||
throw new BadRequest()
|
throw new BadRequest()
|
||||||
}
|
}
|
||||||
|
|
||||||
const { deviceAuthToken, deviceId } = await addChildDevice({
|
const { deviceAuthToken, deviceId, data } = await addChildDevice({
|
||||||
request: req.body,
|
request: req.body,
|
||||||
database,
|
database,
|
||||||
|
eventHandler,
|
||||||
websocket
|
websocket
|
||||||
})
|
})
|
||||||
|
|
||||||
res.json({
|
res.json({
|
||||||
deviceAuthToken,
|
deviceAuthToken,
|
||||||
ownDeviceId: deviceId
|
ownDeviceId: deviceId,
|
||||||
|
data
|
||||||
})
|
})
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
next(ex)
|
next(ex)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* server component for the TimeLimit App
|
* server component for the TimeLimit App
|
||||||
* Copyright (C) 2019 - 2020 Jonas Lochmann
|
* Copyright (C) 2019 - 2022 Jonas Lochmann
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Affero General Public License as
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
@ -47,8 +47,8 @@ export const createApi = ({ database, websocket, connectedDevicesManager, eventH
|
||||||
})
|
})
|
||||||
|
|
||||||
app.use('/auth', createAuthRouter(database))
|
app.use('/auth', createAuthRouter(database))
|
||||||
app.use('/child', createChildRouter({ database, websocket }))
|
app.use('/child', createChildRouter({ database, websocket, eventHandler }))
|
||||||
app.use('/parent', createParentRouter({ database, websocket }))
|
app.use('/parent', createParentRouter({ database, websocket, eventHandler }))
|
||||||
app.use('/purchase', createPurchaseRouter({ database, websocket }))
|
app.use('/purchase', createPurchaseRouter({ database, websocket }))
|
||||||
app.use('/sync', createSyncRouter({ database, websocket, connectedDevicesManager, eventHandler }))
|
app.use('/sync', createSyncRouter({ database, websocket, connectedDevicesManager, eventHandler }))
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,7 @@ import { signInIntoFamily } from '../function/parent/sign-in-into-family'
|
||||||
import { validateU2fIntegrity, U2fValidationError } from '../function/u2f'
|
import { validateU2fIntegrity, U2fValidationError } from '../function/u2f'
|
||||||
import { createIdentityToken, MissingSignSecretException } from '../util/identity-token'
|
import { createIdentityToken, MissingSignSecretException } from '../util/identity-token'
|
||||||
import { WebsocketApi } from '../websocket'
|
import { WebsocketApi } from '../websocket'
|
||||||
|
import { EventHandler } from '../monitoring/eventhandler'
|
||||||
import {
|
import {
|
||||||
isCreateFamilyByMailTokenRequest,
|
isCreateFamilyByMailTokenRequest,
|
||||||
isCreateRegisterDeviceTokenRequest, isLinkParentMailAddressRequest,
|
isCreateRegisterDeviceTokenRequest, isLinkParentMailAddressRequest,
|
||||||
|
@ -38,7 +39,13 @@ import {
|
||||||
isRemoveDeviceRequest, isSignIntoFamilyRequest, isRequestIdentityTokenRequest
|
isRemoveDeviceRequest, isSignIntoFamilyRequest, isRequestIdentityTokenRequest
|
||||||
} from './validator'
|
} from './validator'
|
||||||
|
|
||||||
export const createParentRouter = ({ database, websocket }: {database: Database, websocket: WebsocketApi}) => {
|
export const createParentRouter = ({
|
||||||
|
database, websocket, eventHandler
|
||||||
|
}: {
|
||||||
|
database: Database
|
||||||
|
websocket: WebsocketApi
|
||||||
|
eventHandler: EventHandler
|
||||||
|
}) => {
|
||||||
const router = Router()
|
const router = Router()
|
||||||
|
|
||||||
router.post('/get-status-by-mail-address', json(), async (req, res, next) => {
|
router.post('/get-status-by-mail-address', json(), async (req, res, next) => {
|
||||||
|
@ -75,17 +82,20 @@ export const createParentRouter = ({ database, websocket }: {database: Database,
|
||||||
|
|
||||||
const result = await createFamily({
|
const result = await createFamily({
|
||||||
database,
|
database,
|
||||||
|
eventHandler,
|
||||||
firstParentDevice: req.body.parentDevice,
|
firstParentDevice: req.body.parentDevice,
|
||||||
mailAuthToken: req.body.mailAuthToken,
|
mailAuthToken: req.body.mailAuthToken,
|
||||||
password: req.body.parentPassword,
|
password: req.body.parentPassword,
|
||||||
deviceName: req.body.deviceName,
|
deviceName: req.body.deviceName,
|
||||||
parentName: req.body.parentName,
|
parentName: req.body.parentName,
|
||||||
timeZone: req.body.timeZone
|
timeZone: req.body.timeZone,
|
||||||
|
clientLevel: req.body.clientLevel || null
|
||||||
})
|
})
|
||||||
|
|
||||||
res.json({
|
res.json({
|
||||||
deviceAuthToken: result.deviceAuthToken,
|
deviceAuthToken: result.deviceAuthToken,
|
||||||
ownDeviceId: result.deviceId
|
ownDeviceId: result.deviceId,
|
||||||
|
data: result.data
|
||||||
})
|
})
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
next(ex)
|
next(ex)
|
||||||
|
@ -100,15 +110,18 @@ export const createParentRouter = ({ database, websocket }: {database: Database,
|
||||||
|
|
||||||
const result = await signInIntoFamily({
|
const result = await signInIntoFamily({
|
||||||
database,
|
database,
|
||||||
|
eventHandler,
|
||||||
newDeviceInfo: req.body.parentDevice,
|
newDeviceInfo: req.body.parentDevice,
|
||||||
mailAuthToken: req.body.mailAuthToken,
|
mailAuthToken: req.body.mailAuthToken,
|
||||||
deviceName: req.body.deviceName,
|
deviceName: req.body.deviceName,
|
||||||
|
clientLevel: req.body.clientLevel || null,
|
||||||
websocket
|
websocket
|
||||||
})
|
})
|
||||||
|
|
||||||
res.json({
|
res.json({
|
||||||
deviceAuthToken: result.deviceAuthToken,
|
deviceAuthToken: result.deviceAuthToken,
|
||||||
ownDeviceId: result.deviceId
|
ownDeviceId: result.deviceId,
|
||||||
|
data: result.data
|
||||||
})
|
})
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
next(ex)
|
next(ex)
|
||||||
|
|
|
@ -84,12 +84,14 @@ export interface CreateFamilyByMailTokenRequest {
|
||||||
deviceName: string
|
deviceName: string
|
||||||
timeZone: string
|
timeZone: string
|
||||||
parentName: string
|
parentName: string
|
||||||
|
clientLevel?: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SignIntoFamilyRequest {
|
export interface SignIntoFamilyRequest {
|
||||||
mailAuthToken: string
|
mailAuthToken: string
|
||||||
parentDevice: NewDeviceInfo
|
parentDevice: NewDeviceInfo
|
||||||
deviceName: string
|
deviceName: string
|
||||||
|
clientLevel?: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface RecoverParentPasswordRequest {
|
export interface RecoverParentPasswordRequest {
|
||||||
|
@ -101,6 +103,7 @@ export interface RegisterChildDeviceRequest {
|
||||||
registerToken: string
|
registerToken: string
|
||||||
childDevice: NewDeviceInfo
|
childDevice: NewDeviceInfo
|
||||||
deviceName: string
|
deviceName: string
|
||||||
|
clientLevel?: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CreateRegisterDeviceTokenRequest {
|
export interface CreateRegisterDeviceTokenRequest {
|
||||||
|
|
|
@ -2930,6 +2930,9 @@ export const isCreateFamilyByMailTokenRequest: (value: unknown) => value is Crea
|
||||||
},
|
},
|
||||||
"parentName": {
|
"parentName": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
|
},
|
||||||
|
"clientLevel": {
|
||||||
|
"type": "number"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"additionalProperties": false,
|
"additionalProperties": false,
|
||||||
|
@ -2955,6 +2958,9 @@ export const isSignIntoFamilyRequest: (value: unknown) => value is SignIntoFamil
|
||||||
},
|
},
|
||||||
"deviceName": {
|
"deviceName": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
|
},
|
||||||
|
"clientLevel": {
|
||||||
|
"type": "number"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"additionalProperties": false,
|
"additionalProperties": false,
|
||||||
|
@ -2995,6 +3001,9 @@ export const isRegisterChildDeviceRequest: (value: unknown) => value is Register
|
||||||
},
|
},
|
||||||
"deviceName": {
|
"deviceName": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
|
},
|
||||||
|
"clientLevel": {
|
||||||
|
"type": "number"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"additionalProperties": false,
|
"additionalProperties": false,
|
||||||
|
|
|
@ -22,13 +22,22 @@ import { generateAuthToken, generateVersionId } from '../../util/token'
|
||||||
import { WebsocketApi } from '../../websocket'
|
import { WebsocketApi } from '../../websocket'
|
||||||
import { prepareDeviceEntry } from '../device/prepare-device-entry'
|
import { prepareDeviceEntry } from '../device/prepare-device-entry'
|
||||||
import { notifyClientsAboutChangesDelayed } from '../websocket'
|
import { notifyClientsAboutChangesDelayed } from '../websocket'
|
||||||
|
import { generateServerDataStatus } from '../sync/get-server-data-status'
|
||||||
|
import { EventHandler } from '../../monitoring/eventhandler'
|
||||||
|
import { ServerDataStatus } from '../../object/serverdatastatus'
|
||||||
|
import { createEmptyClientDataStatus } from '../../object/clientdatastatus'
|
||||||
|
|
||||||
export const addChildDevice = async ({ database, websocket, request }: {
|
export const addChildDevice = async ({ database, eventHandler, websocket, request }: {
|
||||||
database: Database
|
database: Database
|
||||||
|
eventHandler: EventHandler
|
||||||
websocket: WebsocketApi
|
websocket: WebsocketApi
|
||||||
request: RegisterChildDeviceRequest
|
request: RegisterChildDeviceRequest
|
||||||
// no transaction here because this is directly called from an API endpoint
|
// no transaction here because this is directly called from an API endpoint
|
||||||
}) => {
|
}): Promise<{
|
||||||
|
deviceId: string
|
||||||
|
deviceAuthToken: string
|
||||||
|
data: ServerDataStatus
|
||||||
|
}> => {
|
||||||
return database.transaction(async (transaction) => {
|
return database.transaction(async (transaction) => {
|
||||||
const entry = await database.addDeviceToken.findOne({
|
const entry = await database.addDeviceToken.findOne({
|
||||||
where: {
|
where: {
|
||||||
|
@ -75,9 +84,19 @@ export const addChildDevice = async ({ database, websocket, request }: {
|
||||||
transaction
|
transaction
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const data = await generateServerDataStatus({
|
||||||
|
database,
|
||||||
|
clientStatus: createEmptyClientDataStatus({ clientLevel: request.clientLevel || null }),
|
||||||
|
familyId: entry.familyId,
|
||||||
|
deviceId,
|
||||||
|
transaction,
|
||||||
|
eventHandler
|
||||||
|
})
|
||||||
|
|
||||||
return {
|
return {
|
||||||
deviceId,
|
deviceId,
|
||||||
deviceAuthToken
|
deviceAuthToken,
|
||||||
|
data
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,25 +16,38 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Conflict } from 'http-errors'
|
import { Conflict } from 'http-errors'
|
||||||
|
import { generateServerDataStatus } from '../sync/get-server-data-status'
|
||||||
import { NewDeviceInfo, PlaintextParentPassword, assertPlaintextParentPasswordValid } from '../../api/schema'
|
import { NewDeviceInfo, PlaintextParentPassword, assertPlaintextParentPasswordValid } from '../../api/schema'
|
||||||
import { Database } from '../../database'
|
import { Database } from '../../database'
|
||||||
import { maxMailNotificationFlags } from '../../database/user'
|
import { maxMailNotificationFlags } from '../../database/user'
|
||||||
|
import { EventHandler } from '../../monitoring/eventhandler'
|
||||||
|
import { ServerDataStatus } from '../../object/serverdatastatus'
|
||||||
|
import { createEmptyClientDataStatus } from '../../object/clientdatastatus'
|
||||||
import {
|
import {
|
||||||
generateAuthToken, generateFamilyId, generateIdWithinFamily, generateVersionId
|
generateAuthToken, generateFamilyId, generateIdWithinFamily, generateVersionId
|
||||||
} from '../../util/token'
|
} from '../../util/token'
|
||||||
import { requireMailAndLocaleByAuthToken } from '../authentication'
|
import { requireMailAndLocaleByAuthToken } from '../authentication'
|
||||||
import { prepareDeviceEntry } from '../device/prepare-device-entry'
|
import { prepareDeviceEntry } from '../device/prepare-device-entry'
|
||||||
|
|
||||||
export const createFamily = async ({ database, mailAuthToken, firstParentDevice, password, timeZone, parentName, deviceName }: {
|
export async function createFamily ({
|
||||||
database: Database,
|
database, eventHandler, mailAuthToken, firstParentDevice,
|
||||||
mailAuthToken: string,
|
password, timeZone, parentName, deviceName, clientLevel
|
||||||
firstParentDevice: NewDeviceInfo,
|
}: {
|
||||||
password: PlaintextParentPassword,
|
database: Database
|
||||||
timeZone: string,
|
eventHandler: EventHandler
|
||||||
parentName: string,
|
mailAuthToken: string
|
||||||
|
firstParentDevice: NewDeviceInfo
|
||||||
|
password: PlaintextParentPassword
|
||||||
|
timeZone: string
|
||||||
|
parentName: string
|
||||||
deviceName: string
|
deviceName: string
|
||||||
|
clientLevel: number | null
|
||||||
// no transaction here because this is directly called from an API endpoint
|
// no transaction here because this is directly called from an API endpoint
|
||||||
}) => {
|
}): Promise<{
|
||||||
|
deviceAuthToken: string
|
||||||
|
deviceId: string
|
||||||
|
data: ServerDataStatus
|
||||||
|
}> {
|
||||||
assertPlaintextParentPasswordValid(password)
|
assertPlaintextParentPasswordValid(password)
|
||||||
|
|
||||||
return database.transaction(async (transaction) => {
|
return database.transaction(async (transaction) => {
|
||||||
|
@ -42,14 +55,14 @@ export const createFamily = async ({ database, mailAuthToken, firstParentDevice,
|
||||||
const mailInfo = await requireMailAndLocaleByAuthToken({ database, mailAuthToken, transaction, invalidate: true })
|
const mailInfo = await requireMailAndLocaleByAuthToken({ database, mailAuthToken, transaction, invalidate: true })
|
||||||
|
|
||||||
// ensure that no family was created for this mail yet
|
// ensure that no family was created for this mail yet
|
||||||
const exisitngUserEntry = await database.user.findOne({
|
const existingUserEntry = await database.user.findOne({
|
||||||
where: {
|
where: {
|
||||||
mail: mailInfo.mail
|
mail: mailInfo.mail
|
||||||
},
|
},
|
||||||
transaction
|
transaction
|
||||||
})
|
})
|
||||||
|
|
||||||
if (exisitngUserEntry) {
|
if (existingUserEntry) {
|
||||||
throw new Conflict()
|
throw new Conflict()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,9 +116,19 @@ export const createFamily = async ({ database, mailAuthToken, firstParentDevice,
|
||||||
isUserKeptSignedIn: true
|
isUserKeptSignedIn: true
|
||||||
}), { transaction })
|
}), { transaction })
|
||||||
|
|
||||||
|
const data = await generateServerDataStatus({
|
||||||
|
database,
|
||||||
|
clientStatus: createEmptyClientDataStatus({ clientLevel }),
|
||||||
|
familyId,
|
||||||
|
deviceId,
|
||||||
|
transaction,
|
||||||
|
eventHandler
|
||||||
|
})
|
||||||
|
|
||||||
return {
|
return {
|
||||||
deviceAuthToken,
|
deviceAuthToken,
|
||||||
deviceId
|
deviceId,
|
||||||
|
data
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,15 +24,21 @@ import { WebsocketApi } from '../../websocket'
|
||||||
import { requireMailAndLocaleByAuthToken } from '../authentication'
|
import { requireMailAndLocaleByAuthToken } from '../authentication'
|
||||||
import { prepareDeviceEntry } from '../device/prepare-device-entry'
|
import { prepareDeviceEntry } from '../device/prepare-device-entry'
|
||||||
import { notifyClientsAboutChangesDelayed } from '../websocket'
|
import { notifyClientsAboutChangesDelayed } from '../websocket'
|
||||||
|
import { generateServerDataStatus } from '../sync/get-server-data-status'
|
||||||
|
import { EventHandler } from '../../monitoring/eventhandler'
|
||||||
|
import { ServerDataStatus } from '../../object/serverdatastatus'
|
||||||
|
import { createEmptyClientDataStatus } from '../../object/clientdatastatus'
|
||||||
|
|
||||||
export const signInIntoFamily = async ({ database, mailAuthToken, newDeviceInfo, deviceName, websocket }: {
|
export const signInIntoFamily = async ({ database, eventHandler, mailAuthToken, newDeviceInfo, deviceName, websocket, clientLevel }: {
|
||||||
database: Database
|
database: Database
|
||||||
|
eventHandler: EventHandler
|
||||||
mailAuthToken: string
|
mailAuthToken: string
|
||||||
newDeviceInfo: NewDeviceInfo
|
newDeviceInfo: NewDeviceInfo
|
||||||
deviceName: string
|
deviceName: string
|
||||||
websocket: WebsocketApi
|
websocket: WebsocketApi
|
||||||
|
clientLevel: number | null
|
||||||
// no transaction here because this is directly called from an API endpoint
|
// no transaction here because this is directly called from an API endpoint
|
||||||
}): Promise<{ deviceId: string; deviceAuthToken: string }> => {
|
}): Promise<{ deviceId: string; deviceAuthToken: string; data: ServerDataStatus }> => {
|
||||||
return database.transaction(async (transaction) => {
|
return database.transaction(async (transaction) => {
|
||||||
const mailInfo = await requireMailAndLocaleByAuthToken({ database, mailAuthToken, transaction, invalidate: true })
|
const mailInfo = await requireMailAndLocaleByAuthToken({ database, mailAuthToken, transaction, invalidate: true })
|
||||||
|
|
||||||
|
@ -94,9 +100,19 @@ export const signInIntoFamily = async ({ database, mailAuthToken, newDeviceInfo,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const data = await generateServerDataStatus({
|
||||||
|
database,
|
||||||
|
clientStatus: createEmptyClientDataStatus({ clientLevel }),
|
||||||
|
familyId: userEntry.familyId,
|
||||||
|
deviceId,
|
||||||
|
transaction,
|
||||||
|
eventHandler
|
||||||
|
})
|
||||||
|
|
||||||
return {
|
return {
|
||||||
deviceId,
|
deviceId,
|
||||||
deviceAuthToken
|
deviceAuthToken,
|
||||||
|
data
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,18 @@ export interface ClientDataStatus {
|
||||||
u2f?: string // last u2f list version
|
u2f?: string // last u2f list version
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function createEmptyClientDataStatus({ clientLevel }: {
|
||||||
|
clientLevel: number | null
|
||||||
|
}): ClientDataStatus {
|
||||||
|
return {
|
||||||
|
devices: '',
|
||||||
|
apps: {},
|
||||||
|
categories: {},
|
||||||
|
users: '',
|
||||||
|
clientLevel: clientLevel || undefined
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export type ClientDataStatusApps = {[key: string]: string} // installedAppsVersionsByDeviceId
|
export type ClientDataStatusApps = {[key: string]: string} // installedAppsVersionsByDeviceId
|
||||||
export type ClientDataStatusCategories = {[key: string]: CategoryDataStatus}
|
export type ClientDataStatusCategories = {[key: string]: CategoryDataStatus}
|
||||||
export type ClientDataStatusDevicesExtended = {[key: string]: DeviceDataStatus}
|
export type ClientDataStatusDevicesExtended = {[key: string]: DeviceDataStatus}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue