Files
standardnotes-server/packages/auth/src/Infra/InversifyExpressUtils/InversifyExpressSubscriptionTokensController.spec.ts
T
Karol SójkoandGitHub c7d575a0ff feat: add files server as a service to home-server (#614)
* wip: add files server as a service to home-server

* wip: introduce home-server controllers without inversify-express-utils decorators. Move in progress

* fix(auth): move remaining home server controllers

* fix(syncing-server): home server controllers

* fix(revisions): home server controllers

* fix: specs

* fix: import for legacy controller

* fix: remove router debug
2023-05-29 14:45:49 +02:00

185 lines
5.9 KiB
TypeScript

import 'reflect-metadata'
import * as express from 'express'
import { results } from 'inversify-express-utils'
import { InversifyExpressSubscriptionTokensController } from './InversifyExpressSubscriptionTokensController'
import { CrossServiceTokenData, TokenEncoderInterface } from '@standardnotes/security'
import { Setting } from '../../Domain/Setting/Setting'
import { SettingServiceInterface } from '../../Domain/Setting/SettingServiceInterface'
import { AuthenticateSubscriptionToken } from '../../Domain/UseCase/AuthenticateSubscriptionToken/AuthenticateSubscriptionToken'
import { CreateSubscriptionToken } from '../../Domain/UseCase/CreateSubscriptionToken/CreateSubscriptionToken'
import { CreateSubscriptionTokenResponse } from '../../Domain/UseCase/CreateSubscriptionToken/CreateSubscriptionTokenResponse'
import { ProjectorInterface } from '../../Projection/ProjectorInterface'
import { User } from '../../Domain/User/User'
import { Role } from '../../Domain/Role/Role'
describe('InversifyExpressSubscriptionTokensController', () => {
let createSubscriptionToken: CreateSubscriptionToken
let authenticateToken: AuthenticateSubscriptionToken
const jwtTTL = 60
let userProjector: ProjectorInterface<User>
let roleProjector: ProjectorInterface<Role>
let settingService: SettingServiceInterface
let extensionKeySetting: Setting
let tokenEncoder: TokenEncoderInterface<CrossServiceTokenData>
let request: express.Request
let response: express.Response
let user: User
let role: Role
const createController = () =>
new InversifyExpressSubscriptionTokensController(
createSubscriptionToken,
authenticateToken,
settingService,
userProjector,
roleProjector,
tokenEncoder,
jwtTTL,
)
beforeEach(() => {
user = {} as jest.Mocked<User>
user.uuid = '123'
user.roles = Promise.resolve([role])
createSubscriptionToken = {} as jest.Mocked<CreateSubscriptionToken>
createSubscriptionToken.execute = jest.fn().mockReturnValue({
subscriptionToken: {
token: 'test',
},
} as jest.Mocked<CreateSubscriptionTokenResponse>)
authenticateToken = {} as jest.Mocked<AuthenticateSubscriptionToken>
authenticateToken.execute = jest.fn().mockReturnValue({
success: true,
user,
})
userProjector = {} as jest.Mocked<ProjectorInterface<User>>
userProjector.projectSimple = jest.fn().mockReturnValue({ bar: 'baz' })
roleProjector = {} as jest.Mocked<ProjectorInterface<Role>>
roleProjector.projectSimple = jest.fn().mockReturnValue({ name: 'role1', uuid: '1-3-4' })
extensionKeySetting = {
name: 'EXTENSION_KEY',
value: 'abc123',
} as jest.Mocked<Setting>
settingService = {} as jest.Mocked<SettingServiceInterface>
settingService.findSettingWithDecryptedValue = jest.fn().mockReturnValue(extensionKeySetting)
tokenEncoder = {} as jest.Mocked<TokenEncoderInterface<CrossServiceTokenData>>
tokenEncoder.encodeExpirableToken = jest.fn().mockReturnValue('foobar')
request = {
headers: {},
body: {},
params: {},
} as jest.Mocked<express.Request>
response = {
locals: {},
} as jest.Mocked<express.Response>
})
it('should create an subscription token for authenticated user', async () => {
response.locals.user = {
uuid: '1-2-3',
}
const httpResponse = <results.JsonResult>await createController().createToken(request, response)
const result = await httpResponse.executeAsync()
expect(createSubscriptionToken.execute).toHaveBeenCalledWith({
userUuid: '1-2-3',
})
expect(result.statusCode).toEqual(200)
})
it('should not create an subscription token if session has read only access', async () => {
response.locals.user = {
uuid: '1-2-3',
}
response.locals.readOnlyAccess = true
const httpResponse = <results.JsonResult>await createController().createToken(request, response)
const result = await httpResponse.executeAsync()
expect(createSubscriptionToken.execute).not.toHaveBeenCalled()
expect(result.statusCode).toEqual(401)
})
it('should validate an subscription token for user', async () => {
request.params.token = 'test'
const httpResponse = <results.JsonResult>await createController().validate(request)
const result = await httpResponse.executeAsync()
expect(authenticateToken.execute).toHaveBeenCalledWith({
token: 'test',
})
const responseBody = JSON.parse(await result.content.readAsStringAsync())
expect(responseBody.authToken).toEqual('foobar')
expect(result.statusCode).toEqual(200)
expect(tokenEncoder.encodeExpirableToken).toHaveBeenCalledWith(
{
extensionKey: 'abc123',
roles: [
{
name: 'role1',
uuid: '1-3-4',
},
],
user: {
bar: 'baz',
},
},
60,
)
})
it('should validate an subscription token for user without an extension key setting', async () => {
request.params.token = 'test'
settingService.findSettingWithDecryptedValue = jest.fn().mockReturnValue(null)
const httpResponse = <results.JsonResult>await createController().validate(request)
const result = await httpResponse.executeAsync()
expect(authenticateToken.execute).toHaveBeenCalledWith({
token: 'test',
})
const responseBody = JSON.parse(await result.content.readAsStringAsync())
expect(responseBody.authToken).toEqual('foobar')
expect(result.statusCode).toEqual(200)
})
it('should not validate an subscription token for user if it is invalid', async () => {
request.params.token = 'test'
authenticateToken.execute = jest.fn().mockReturnValue({
success: false,
})
const httpResponse = <results.JsonResult>await createController().validate(request)
const result = await httpResponse.executeAsync()
expect(authenticateToken.execute).toHaveBeenCalledWith({
token: 'test',
})
expect(result.statusCode).toEqual(401)
})
})