mirror of
https://github.com/feathersjs/feathers.git
synced 2026-01-25 15:23:13 +00:00
211 lines
6.1 KiB
TypeScript
211 lines
6.1 KiB
TypeScript
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
|
import { omit } from 'lodash'
|
|
import { strict as assert } from 'assert'
|
|
import { default as _axios } from 'axios'
|
|
import { feathers } from '@feathersjs/feathers'
|
|
import { createApplication } from '@feathersjs/authentication-local/test/fixture'
|
|
import { authenticate, AuthenticationResult } from '@feathersjs/authentication'
|
|
import * as express from '../src'
|
|
|
|
const expressify = express.default
|
|
const axios = _axios.create({
|
|
baseURL: 'http://localhost:9876/'
|
|
})
|
|
|
|
describe('@feathersjs/express/authentication', () => {
|
|
const email = 'expresstest@authentication.com'
|
|
const password = 'superexpress'
|
|
|
|
let app: express.Application
|
|
let user: any
|
|
let authResult: AuthenticationResult
|
|
|
|
before(async () => {
|
|
const expressApp = expressify(feathers()).use(express.json()).configure(express.rest())
|
|
|
|
app = createApplication(expressApp as any) as unknown as express.Application
|
|
|
|
await app.listen(9876)
|
|
|
|
app.use('/dummy', {
|
|
get(id, params) {
|
|
return Promise.resolve({ id, params })
|
|
}
|
|
})
|
|
|
|
// @ts-ignore
|
|
app.use('/protected', express.authenticate('jwt'), (req, res) => {
|
|
res.json(req.feathers.user)
|
|
})
|
|
|
|
app.use(
|
|
express.errorHandler({
|
|
logger: false
|
|
})
|
|
)
|
|
|
|
app.service('dummy').hooks({
|
|
before: [authenticate('jwt')]
|
|
})
|
|
|
|
const result = await app.service('users').create({ email, password })
|
|
|
|
user = result
|
|
|
|
const res = await axios.post<any>('/authentication', {
|
|
strategy: 'local',
|
|
password,
|
|
email
|
|
})
|
|
|
|
authResult = res.data
|
|
})
|
|
|
|
after(() => app.teardown())
|
|
|
|
describe('service authentication', () => {
|
|
it('successful local authentication', () => {
|
|
assert.ok(authResult.accessToken)
|
|
assert.deepStrictEqual(omit(authResult.authentication, 'payload'), {
|
|
strategy: 'local'
|
|
})
|
|
assert.strictEqual(authResult.user.email, email)
|
|
assert.strictEqual(authResult.user.password, undefined)
|
|
})
|
|
|
|
it('local authentication with wrong password fails', async () => {
|
|
try {
|
|
await axios.post<any>('/authentication', {
|
|
strategy: 'local',
|
|
password: 'wrong',
|
|
email
|
|
})
|
|
assert.fail('Should never get here')
|
|
} catch (error: any) {
|
|
const { data } = error.response
|
|
assert.strictEqual(data.name, 'NotAuthenticated')
|
|
assert.strictEqual(data.message, 'Invalid login')
|
|
}
|
|
})
|
|
|
|
it('authenticating with JWT works but returns same accessToken', async () => {
|
|
const { accessToken } = authResult
|
|
const { data } = await axios.post<any>('/authentication', {
|
|
strategy: 'jwt',
|
|
accessToken
|
|
})
|
|
|
|
assert.strictEqual(data.accessToken, accessToken)
|
|
assert.strictEqual(data.authentication.strategy, 'jwt')
|
|
assert.strictEqual(data.authentication.payload.sub, user.id.toString())
|
|
assert.strictEqual(data.user.email, email)
|
|
})
|
|
|
|
it('can make a protected request with Authorization header', async () => {
|
|
const { accessToken } = authResult
|
|
|
|
const {
|
|
data,
|
|
data: { params }
|
|
} = await axios.get<any>('/dummy/dave', {
|
|
headers: {
|
|
Authorization: accessToken
|
|
}
|
|
})
|
|
|
|
assert.strictEqual(data.id, 'dave')
|
|
assert.deepStrictEqual(params.user, user)
|
|
assert.strictEqual(params.authentication.accessToken, accessToken)
|
|
})
|
|
|
|
it('errors when there are no authStrategies and parseStrategies', async () => {
|
|
const { accessToken } = authResult
|
|
app.get('authentication').authStrategies = []
|
|
delete app.get('authentication').parseStrategies
|
|
|
|
try {
|
|
await axios.get<any>('/dummy/dave', {
|
|
headers: {
|
|
Authorization: accessToken
|
|
}
|
|
})
|
|
assert.fail('Should never get here')
|
|
} catch (error: any) {
|
|
assert.strictEqual(error.response.data.name, 'NotAuthenticated')
|
|
app.get('authentication').authStrategies = ['jwt', 'local']
|
|
}
|
|
})
|
|
|
|
it('can make a protected request with Authorization header and bearer scheme', async () => {
|
|
const { accessToken } = authResult
|
|
|
|
const {
|
|
data,
|
|
data: { params }
|
|
} = await axios.get<any>('/dummy/dave', {
|
|
headers: {
|
|
Authorization: ` Bearer: ${accessToken}`
|
|
}
|
|
})
|
|
|
|
assert.strictEqual(data.id, 'dave')
|
|
assert.deepStrictEqual(params.user, user)
|
|
assert.strictEqual(params.authentication.accessToken, accessToken)
|
|
})
|
|
})
|
|
|
|
describe('authenticate middleware', () => {
|
|
it('errors without valid strategies', () => {
|
|
try {
|
|
// @ts-ignore
|
|
authenticate()
|
|
assert.fail('Should never get here')
|
|
} catch (error: any) {
|
|
assert.strictEqual(error.message, 'The authenticate hook needs at least one allowed strategy')
|
|
}
|
|
})
|
|
|
|
it('protected endpoint fails when JWT is not present', () => {
|
|
return axios
|
|
.get<any>('/protected')
|
|
.then(() => {
|
|
assert.fail('Should never get here')
|
|
})
|
|
.catch((error) => {
|
|
const { data } = error.response
|
|
|
|
assert.strictEqual(data.name, 'NotAuthenticated')
|
|
assert.strictEqual(data.message, 'Not authenticated')
|
|
})
|
|
})
|
|
|
|
it.skip('protected endpoint fails with invalid Authorization header', async () => {
|
|
try {
|
|
await axios.get<any>('/protected', {
|
|
headers: {
|
|
Authorization: 'Bearer: something wrong'
|
|
}
|
|
})
|
|
assert.fail('Should never get here')
|
|
} catch (error: any) {
|
|
const { data } = error.response
|
|
|
|
assert.strictEqual(data.name, 'NotAuthenticated')
|
|
assert.strictEqual(data.message, 'Not authenticated')
|
|
}
|
|
})
|
|
|
|
it('can request protected endpoint with JWT present', async () => {
|
|
const { data } = await axios.get<any>('/protected', {
|
|
headers: {
|
|
Authorization: `Bearer ${authResult.accessToken}`
|
|
}
|
|
})
|
|
|
|
assert.strictEqual(data.email, user.email)
|
|
assert.strictEqual(data.id, user.id)
|
|
assert.strictEqual(data.password, user.password)
|
|
})
|
|
})
|
|
})
|