diff --git a/src/auth/auth.admin.ts b/src/auth/auth.admin.ts new file mode 100644 index 0000000..f657f11 --- /dev/null +++ b/src/auth/auth.admin.ts @@ -0,0 +1,32 @@ +import type { Services } from '#root/utils/services.ts'; +import { Config } from '#root/config/config.ts'; +import type { Statement } from './auth.schemas.ts'; +import type { AuthProvider } from './auth.provider.ts'; + +const adminStatements: Statement[] = [ + { + effect: 'allow', + resources: ['**'], + actions: ['**'], + }, +]; + +class AdminAuth implements AuthProvider { + #services: Services; + + constructor(services: Services) { + this.#services = services; + } + + public getAccess = async (token: string) => { + const config = this.#services.get(Config); + if (!config.adminToken || token !== config.adminToken) { + throw new Error('Invalid admin token'); + } + return { + statements: adminStatements, + }; + }; +} + +export { AdminAuth }; diff --git a/src/auth/auth.jwt.ts b/src/auth/auth.jwt.ts index dda8080..50f7f9a 100644 --- a/src/auth/auth.jwt.ts +++ b/src/auth/auth.jwt.ts @@ -22,7 +22,7 @@ class JwtAuth implements AuthProvider { public generate = (options: TokenBody) => { const config = this.#services.get(Config); - const { tokenSecret } = config; + const { jwtSecret: tokenSecret } = config; if (!tokenSecret) { throw new Error('Token secret does not exist'); } @@ -32,7 +32,7 @@ class JwtAuth implements AuthProvider { public getAccess = async (token: string) => { const config = this.#services.get(Config); - const { tokenSecret } = config; + const { jwtSecret: tokenSecret } = config; if (!tokenSecret) { throw new Error('Token secret does not exist'); } diff --git a/src/backbone.ts b/src/backbone.ts index 02f54de..caf869e 100644 --- a/src/backbone.ts +++ b/src/backbone.ts @@ -1,3 +1,4 @@ +import { AdminAuth } from './auth/auth.admin.ts'; import { JwtAuth } from './auth/auth.jwt.ts'; import { K8sAuth } from './auth/auth.k8s.ts'; import { OidcAuth } from './auth/auth.oidc.ts'; @@ -56,8 +57,11 @@ class Backbone { if (this.config.oidc.enabled) { this.sessionProvider.register('oidc', this.#services.get(OidcAuth)); } - if (this.config.tokenSecret) { - this.sessionProvider.register('token', this.#services.get(JwtAuth)); + if (this.config.jwtSecret) { + this.sessionProvider.register('jwt', this.#services.get(JwtAuth)); + } + if (this.config.adminToken) { + this.sessionProvider.register('admin', this.#services.get(AdminAuth)); } }; diff --git a/src/config/config.ts b/src/config/config.ts index 2a7226c..cbdea15 100644 --- a/src/config/config.ts +++ b/src/config/config.ts @@ -1,5 +1,5 @@ class Config { - public get tokenSecret() { + public get jwtSecret() { return process.env.TOKEN_SECRET; } diff --git a/src/server/server.ts b/src/server/server.ts index c962d7b..9e27782 100644 --- a/src/server/server.ts +++ b/src/server/server.ts @@ -13,12 +13,12 @@ import fastify, { type FastifyInstance } from 'fastify'; import fastifyWebSocket from '@fastify/websocket'; import { createWebSocketStream } from 'ws'; -import { Session } from '../access/access.session.ts'; import { api } from '../api/api.ts'; -import { AccessHandler } from '#root/access/access.handler.ts'; import { TopicsHandler } from '#root/topics/topics.handler.ts'; import type { Services } from '#root/utils/services.ts'; +import { Session } from '#root/services/sessions/sessions.session.ts'; +import { SessionProvider } from '#root/services/sessions/sessions.provider.ts'; type Aedes = ReturnType; @@ -57,8 +57,8 @@ class MqttServer { if (!username || !password) { throw new Error('unauthorized'); } - const accessHandler = this.#services.get(AccessHandler); - const auth = await accessHandler.validate(username, password.toString('utf8')); + const sessionProvider = this.#services.get(SessionProvider); + const auth = await sessionProvider.validate(username, password.toString('utf8')); client.session = new Session(auth); callback(null, true); } catch { diff --git a/tests/utils/utils.world.ts b/tests/utils/utils.world.ts index af425cd..dda922c 100644 --- a/tests/utils/utils.world.ts +++ b/tests/utils/utils.world.ts @@ -6,6 +6,7 @@ import { TopicsStore } from '#root/topics/topics.store.ts'; import { Backbone } from '#root/backbone.ts'; import { JwtAuth } from '#root/auth/auth.jwt.ts'; import type { Statement } from '#root/auth/auth.schemas.ts'; +import { Config } from '#root/config/config.ts'; type CreateSocketOptions = { port: number; @@ -29,6 +30,10 @@ type WorldOptions = { const createWorld = async (options: WorldOptions) => { const { topics = [] } = options; const backbone = new Backbone(); + backbone.services.set(Config, { + jwtSecret: 'test', + adminToken: 'test', + }); const accessTokens = backbone.services.get(JwtAuth); backbone.sessionProvider.register('token', accessTokens); const topicsStore = new TopicsStore();