|
| 1 | +import { Request as ArkstackRequest, arkstackHttpPlugin } from '../../http/src' |
1 | 2 | import { afterAll, beforeEach, describe, expect, it } from 'vitest' |
2 | 3 | import { authSecret, cleanupAuthRecords, createAuthToken, createAuthUser, createPersonalAccessToken } from './fixtures/auth' |
3 | 4 |
|
4 | 5 | import { Auth } from '../src' |
5 | 6 | import { Router as ClearRouter } from 'clear-router/express' |
| 7 | +import { Container } from 'clear-router/decorators' |
6 | 8 | import { Hash } from '../../common/src' |
7 | 9 | import { auth } from '../../driver-express/src/middlewares/auth' |
8 | 10 | import express from 'express' |
@@ -50,6 +52,62 @@ describe('Express auth integration', () => { |
50 | 52 | expect(response.body.authToken).toBe(token) |
51 | 53 | }) |
52 | 54 |
|
| 55 | + it('hydrates the container-bound Arkstack request after authentication', async () => { |
| 56 | + const user = await createAuthUser() |
| 57 | + const token = await createAuthToken(user.id) |
| 58 | + |
| 59 | + await createPersonalAccessToken(user.id, token) |
| 60 | + |
| 61 | + const app = express() |
| 62 | + const router = express.Router() |
| 63 | + const Router = createRouter('bound-request') |
| 64 | + |
| 65 | + await import('../../http/src/setup') |
| 66 | + await (Router as any).pluginsReady() |
| 67 | + |
| 68 | + expect(Container.has(ArkstackRequest)).toBe(true) |
| 69 | + |
| 70 | + await Router.use(arkstackHttpPlugin) |
| 71 | + Router.configure({ |
| 72 | + container: { |
| 73 | + enabled: true, |
| 74 | + autoDiscover: true, |
| 75 | + }, |
| 76 | + }) |
| 77 | + Router.get('/account/request', async (ctx) => { |
| 78 | + const req = await Container.resolve(ArkstackRequest, ctx) |
| 79 | + |
| 80 | + return { |
| 81 | + authToken: req?.authToken, |
| 82 | + authUserFromAuthId: (req?.auth as Auth | undefined)?.user()?.id, |
| 83 | + authUserId: req?.authUser?.id, |
| 84 | + constructorName: req?.constructor.name, |
| 85 | + hasIp: Boolean(req?.ip), |
| 86 | + hasSource: Boolean(req?.source), |
| 87 | + isArkstackRequest: req instanceof ArkstackRequest, |
| 88 | + userId: req?.user?.id, |
| 89 | + } |
| 90 | + }, [auth]) |
| 91 | + Router.apply(router) |
| 92 | + app.use(router) |
| 93 | + |
| 94 | + const response = await request(app) |
| 95 | + .get('/account/request') |
| 96 | + .set('Authorization', `Bearer ${token}`) |
| 97 | + .expect(200) |
| 98 | + |
| 99 | + expect(response.body).toMatchObject({ |
| 100 | + authToken: token, |
| 101 | + constructorName: 'Request', |
| 102 | + hasIp: true, |
| 103 | + hasSource: true, |
| 104 | + isArkstackRequest: true, |
| 105 | + }) |
| 106 | + expect(String(response.body.authUserFromAuthId)).toBe(String(user.id)) |
| 107 | + expect(String(response.body.authUserId)).toBe(String(user.id)) |
| 108 | + expect(String(response.body.userId)).toBe(String(user.id)) |
| 109 | + }) |
| 110 | + |
53 | 111 | it('returns an authentication error when the bearer token is missing', async () => { |
54 | 112 | const app = express() |
55 | 113 |
|
@@ -89,6 +147,7 @@ describe('Express auth integration', () => { |
89 | 147 | const personalAccessToken = await auth.login(email, password) |
90 | 148 |
|
91 | 149 | return res.status(200).json({ |
| 150 | + // @ts-expect-error req.auth is typed from built dependencies |
92 | 151 | authMatches: req.auth === auth, |
93 | 152 | authToken: req.authToken, |
94 | 153 | authUserFromAuthId: req.auth?.user()?.id, |
@@ -131,6 +190,7 @@ describe('Express auth integration', () => { |
131 | 190 | const personalAccessToken = await auth.create(user) |
132 | 191 |
|
133 | 192 | return res.status(201).json({ |
| 193 | + // @ts-expect-error req.auth is typed from built dependencies |
134 | 194 | authMatches: req.auth === auth, |
135 | 195 | authToken: req.authToken, |
136 | 196 | authUserFromAuthId: req.auth?.user()?.id, |
|
0 commit comments