homebridge-securitysystem 10.1.0 → 11.0.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +29 -0
- package/config.schema.json +5 -6
- package/dist/interfaces/options-interface.d.ts +1 -1
- package/dist/schemas/arming-lock-schema.d.ts +10 -0
- package/dist/schemas/arming-lock-schema.js +12 -0
- package/dist/schemas/arming-lock-schema.js.map +1 -0
- package/dist/schemas/error-schema.d.ts +4 -0
- package/dist/schemas/error-schema.js +7 -0
- package/dist/schemas/error-schema.js.map +1 -0
- package/dist/schemas/mode-request-schema.d.ts +11 -0
- package/dist/schemas/mode-request-schema.js +18 -0
- package/dist/schemas/mode-request-schema.js.map +1 -0
- package/dist/schemas/status-response-schema.d.ts +7 -0
- package/dist/schemas/status-response-schema.js +10 -0
- package/dist/schemas/status-response-schema.js.map +1 -0
- package/dist/services/configuration-service.js +2 -1
- package/dist/services/configuration-service.js.map +1 -1
- package/dist/services/server-service.d.ts +3 -3
- package/dist/services/server-service.js +160 -76
- package/dist/services/server-service.js.map +1 -1
- package/package.json +5 -2
- package/src/interfaces/options-interface.ts +1 -1
- package/src/schemas/arming-lock-schema.ts +12 -0
- package/src/schemas/error-schema.ts +7 -0
- package/src/schemas/mode-request-schema.ts +18 -0
- package/src/schemas/status-response-schema.ts +10 -0
- package/src/services/configuration-service.ts +2 -1
- package/src/services/server-service.ts +179 -89
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,34 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## v11.0.0-beta.1 - 2026-04-18
|
|
4
|
+
|
|
5
|
+
<!-- Release notes generated using configuration in .github/release.yml at v11.0.0-beta.1 -->
|
|
6
|
+
|
|
7
|
+
## What's Changed
|
|
8
|
+
### 💥 Breaking Changes
|
|
9
|
+
* Add OpenAPI documentation and refactor API endpoints by @MiguelRipoll23 in https://github.com/MiguelRipoll23/homebridge-securitysystem/pull/758
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
**Full Changelog**: https://github.com/MiguelRipoll23/homebridge-securitysystem/compare/v10.1.0...v11.0.0-beta.1
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
## v10.1.0 - 2026-04-18
|
|
16
|
+
|
|
17
|
+
<!-- Release notes generated using configuration in .github/release.yml at v10.1.0 -->
|
|
18
|
+
|
|
19
|
+
## What's Changed
|
|
20
|
+
### ✨ Enhancements
|
|
21
|
+
* feat: add custom trip mode switches per mode via config by @MiguelRipoll23 in https://github.com/MiguelRipoll23/homebridge-securitysystem/pull/750
|
|
22
|
+
### 📦 Dependencies
|
|
23
|
+
* build(deps-dev): bump typescript from 6.0.2 to 6.0.3 by @dependabot[bot] in https://github.com/MiguelRipoll23/homebridge-securitysystem/pull/749
|
|
24
|
+
### 🛠️ Other Changes
|
|
25
|
+
* fix: resolve Service|Service[] type errors and CHANGELOG detection bug by @MiguelRipoll23 in https://github.com/MiguelRipoll23/homebridge-securitysystem/pull/752
|
|
26
|
+
* Refactor trip switches: prefix custom switches and add comprehensive tests by @MiguelRipoll23 in https://github.com/MiguelRipoll23/homebridge-securitysystem/pull/755
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
**Full Changelog**: https://github.com/MiguelRipoll23/homebridge-securitysystem/compare/v10.0.0...v10.1.0
|
|
30
|
+
|
|
31
|
+
|
|
3
32
|
## v10.1.0-beta.3 - 2026-04-18
|
|
4
33
|
|
|
5
34
|
<!-- Release notes generated using configuration in .github/release.yml at v10.1.0-beta.3 -->
|
package/config.schema.json
CHANGED
|
@@ -536,13 +536,12 @@
|
|
|
536
536
|
"minimum": 0,
|
|
537
537
|
"placeholder": 80
|
|
538
538
|
},
|
|
539
|
-
"
|
|
540
|
-
"title": "
|
|
541
|
-
"description": "
|
|
542
|
-
"type": "
|
|
539
|
+
"server_api_key": {
|
|
540
|
+
"title": "API Key",
|
|
541
|
+
"description": "A key used to protect the server and authenticate requests.",
|
|
542
|
+
"type": "string",
|
|
543
543
|
"required": false,
|
|
544
|
-
"
|
|
545
|
-
"placeholder": "XXXX"
|
|
544
|
+
"placeholder": "your-api-key"
|
|
546
545
|
},
|
|
547
546
|
"webhook_url": {
|
|
548
547
|
"title": "Base URL",
|
|
@@ -75,7 +75,7 @@ export interface SecuritySystemOptions {
|
|
|
75
75
|
audioExtraVariables: AudioVariable[];
|
|
76
76
|
audioSwitch: boolean;
|
|
77
77
|
serverPort: number | null;
|
|
78
|
-
|
|
78
|
+
serverApiKey: string | null;
|
|
79
79
|
commandTargetHome: string | null;
|
|
80
80
|
commandTargetAway: string | null;
|
|
81
81
|
commandTargetNight: string | null;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { z } from '@hono/zod-openapi';
|
|
2
|
+
export const ArmingLockRequestSchema = z
|
|
3
|
+
.object({
|
|
4
|
+
mode: z
|
|
5
|
+
.enum(['global', 'home', 'away', 'night'])
|
|
6
|
+
.openapi({ example: 'home', description: 'Arming lock mode to update' }),
|
|
7
|
+
value: z
|
|
8
|
+
.boolean()
|
|
9
|
+
.openapi({ example: true, description: 'True to enable the arming lock, false to disable it' }),
|
|
10
|
+
})
|
|
11
|
+
.openapi('ArmingLockRequest');
|
|
12
|
+
//# sourceMappingURL=arming-lock-schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"arming-lock-schema.js","sourceRoot":"","sources":["../../src/schemas/arming-lock-schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,mBAAmB,CAAC;AAEtC,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC;KACrC,MAAM,CAAC;IACN,IAAI,EAAE,CAAC;SACJ,IAAI,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;SACzC,OAAO,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,4BAA4B,EAAE,CAAC;IAC1E,KAAK,EAAE,CAAC;SACL,OAAO,EAAE;SACT,OAAO,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,qDAAqD,EAAE,CAAC;CAClG,CAAC;KACD,OAAO,CAAC,mBAAmB,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-schema.js","sourceRoot":"","sources":["../../src/schemas/error-schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,mBAAmB,CAAC;AAEtC,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC;KACzB,MAAM,CAAC;IACN,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,iBAAiB,EAAE,CAAC;CAC3D,CAAC;KACD,OAAO,CAAC,OAAO,CAAC,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { z } from '@hono/zod-openapi';
|
|
2
|
+
export declare const ModeRequestSchema: z.ZodObject<{
|
|
3
|
+
mode: z.ZodEnum<{
|
|
4
|
+
off: "off";
|
|
5
|
+
home: "home";
|
|
6
|
+
away: "away";
|
|
7
|
+
night: "night";
|
|
8
|
+
triggered: "triggered";
|
|
9
|
+
}>;
|
|
10
|
+
delay: z.ZodOptional<z.ZodNumber>;
|
|
11
|
+
}, z.core.$strip>;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { z } from '@hono/zod-openapi';
|
|
2
|
+
export const ModeRequestSchema = z
|
|
3
|
+
.object({
|
|
4
|
+
mode: z
|
|
5
|
+
.enum(['home', 'away', 'night', 'off', 'triggered'])
|
|
6
|
+
.openapi({ example: 'home', description: 'Target security mode to activate' }),
|
|
7
|
+
delay: z
|
|
8
|
+
.number()
|
|
9
|
+
.int()
|
|
10
|
+
.nonnegative()
|
|
11
|
+
.optional()
|
|
12
|
+
.openapi({
|
|
13
|
+
example: 5000,
|
|
14
|
+
description: 'Optional delay in milliseconds before applying the mode change',
|
|
15
|
+
}),
|
|
16
|
+
})
|
|
17
|
+
.openapi('ModeRequest');
|
|
18
|
+
//# sourceMappingURL=mode-request-schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mode-request-schema.js","sourceRoot":"","sources":["../../src/schemas/mode-request-schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,mBAAmB,CAAC;AAEtC,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC;KAC/B,MAAM,CAAC;IACN,IAAI,EAAE,CAAC;SACJ,IAAI,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,WAAW,CAAC,CAAC;SACnD,OAAO,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,kCAAkC,EAAE,CAAC;IAChF,KAAK,EAAE,CAAC;SACL,MAAM,EAAE;SACR,GAAG,EAAE;SACL,WAAW,EAAE;SACb,QAAQ,EAAE;SACV,OAAO,CAAC;QACP,OAAO,EAAE,IAAI;QACb,WAAW,EAAE,gEAAgE;KAC9E,CAAC;CACL,CAAC;KACD,OAAO,CAAC,aAAa,CAAC,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { z } from '@hono/zod-openapi';
|
|
2
|
+
export const StatusResponseSchema = z
|
|
3
|
+
.object({
|
|
4
|
+
arming: z.boolean().openapi({ example: false, description: 'Whether the system is currently arming' }),
|
|
5
|
+
current_mode: z.string().openapi({ example: 'off', description: 'The current active mode' }),
|
|
6
|
+
target_mode: z.string().openapi({ example: 'home', description: 'The target mode being transitioned to' }),
|
|
7
|
+
tripped: z.boolean().openapi({ example: false, description: 'Whether a trip switch is active' }),
|
|
8
|
+
})
|
|
9
|
+
.openapi('StatusResponse');
|
|
10
|
+
//# sourceMappingURL=status-response-schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status-response-schema.js","sourceRoot":"","sources":["../../src/schemas/status-response-schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,mBAAmB,CAAC;AAEtC,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC;KAClC,MAAM,CAAC;IACN,MAAM,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,wCAAwC,EAAE,CAAC;IACtG,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,yBAAyB,EAAE,CAAC;IAC5F,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,uCAAuC,EAAE,CAAC;IAC1G,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,iCAAiC,EAAE,CAAC;CACjG,CAAC;KACD,OAAO,CAAC,gBAAgB,CAAC,CAAC"}
|
|
@@ -149,7 +149,8 @@ export class ConfigurationService {
|
|
|
149
149
|
audioSwitch: this.bool(raw, 'audio_switch', false),
|
|
150
150
|
// Server
|
|
151
151
|
serverPort: this.num(raw, 'server_port'),
|
|
152
|
-
|
|
152
|
+
// TODO: Remove serverCode fallback in future major version
|
|
153
|
+
serverApiKey: this.str(raw, 'server_api_key') ?? (this.num(raw, 'server_code') !== null ? String(this.num(raw, 'server_code')) : null),
|
|
153
154
|
// Shell commands
|
|
154
155
|
commandTargetHome: this.str(raw, 'command_target_home'),
|
|
155
156
|
commandTargetAway: this.str(raw, 'command_target_away'),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"configuration-service.js","sourceRoot":"","sources":["../../src/services/configuration-service.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"configuration-service.js","sourceRoot":"","sources":["../../src/services/configuration-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -15,11 +15,11 @@ export declare class ServerService {
|
|
|
15
15
|
private readonly application;
|
|
16
16
|
constructor(log: Logging, options: SecuritySystemOptions, state: SystemState, stateHandler: StateHandler, tripHandler: TripHandler, switchHandler: SwitchHandler);
|
|
17
17
|
start(): void;
|
|
18
|
+
private createAuthMiddleware;
|
|
18
19
|
private registerRoutes;
|
|
19
20
|
/**
|
|
20
|
-
*
|
|
21
|
-
* or null
|
|
21
|
+
* Validates the Authorization: Bearer <key> header when serverApiKey is configured.
|
|
22
|
+
* Returns an error Response on failure, or null to allow the request through.
|
|
22
23
|
*/
|
|
23
24
|
private authenticate;
|
|
24
|
-
private parseDelay;
|
|
25
25
|
}
|
|
@@ -1,8 +1,96 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { OpenAPIHono, createRoute } from '@hono/zod-openapi';
|
|
2
2
|
import { serve } from '@hono/node-server';
|
|
3
|
+
import { Scalar } from '@scalar/hono-api-reference';
|
|
3
4
|
import { SecurityState } from '../types/security-state-type.js';
|
|
4
5
|
import { OriginType } from '../types/origin-type.js';
|
|
5
6
|
import { stateToMode } from '../utils/state-util.js';
|
|
7
|
+
import { ErrorSchema } from '../schemas/error-schema.js';
|
|
8
|
+
import { StatusResponseSchema } from '../schemas/status-response-schema.js';
|
|
9
|
+
import { ModeRequestSchema } from '../schemas/mode-request-schema.js';
|
|
10
|
+
import { ArmingLockRequestSchema } from '../schemas/arming-lock-schema.js';
|
|
11
|
+
const MODE_TO_STATE = {
|
|
12
|
+
home: SecurityState.HOME,
|
|
13
|
+
away: SecurityState.AWAY,
|
|
14
|
+
night: SecurityState.NIGHT,
|
|
15
|
+
off: SecurityState.OFF,
|
|
16
|
+
};
|
|
17
|
+
const AUTH_RESPONSES = {
|
|
18
|
+
401: {
|
|
19
|
+
content: { 'application/json': { schema: ErrorSchema } },
|
|
20
|
+
description: 'API key required',
|
|
21
|
+
},
|
|
22
|
+
403: {
|
|
23
|
+
content: { 'application/json': { schema: ErrorSchema } },
|
|
24
|
+
description: 'API key invalid or blocked',
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
const statusRoute = createRoute({
|
|
28
|
+
method: 'get',
|
|
29
|
+
path: '/status',
|
|
30
|
+
summary: 'Get system status',
|
|
31
|
+
description: 'Returns the current arming state, active mode, target mode, and trip status of the security system.',
|
|
32
|
+
security: [{ BearerAuth: [] }],
|
|
33
|
+
responses: {
|
|
34
|
+
200: {
|
|
35
|
+
content: { 'application/json': { schema: StatusResponseSchema } },
|
|
36
|
+
description: 'Current system status',
|
|
37
|
+
},
|
|
38
|
+
...AUTH_RESPONSES,
|
|
39
|
+
},
|
|
40
|
+
});
|
|
41
|
+
const modeRoute = createRoute({
|
|
42
|
+
method: 'put',
|
|
43
|
+
path: '/mode',
|
|
44
|
+
summary: 'Change security mode',
|
|
45
|
+
description: 'Sets the target security mode. Supported modes: home, away, night, off, triggered. ' +
|
|
46
|
+
'Use "triggered" to activate the alarm. An optional delay (ms) defers the transition.',
|
|
47
|
+
security: [{ BearerAuth: [] }],
|
|
48
|
+
request: {
|
|
49
|
+
body: {
|
|
50
|
+
content: {
|
|
51
|
+
'application/json': {
|
|
52
|
+
schema: ModeRequestSchema,
|
|
53
|
+
example: { mode: 'home', delay: 5000 },
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
required: true,
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
responses: {
|
|
60
|
+
204: { description: 'Mode change accepted' },
|
|
61
|
+
...AUTH_RESPONSES,
|
|
62
|
+
409: {
|
|
63
|
+
content: { 'application/json': { schema: ErrorSchema } },
|
|
64
|
+
description: 'Mode change rejected by the system',
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
});
|
|
68
|
+
const armingLockRoute = createRoute({
|
|
69
|
+
method: 'put',
|
|
70
|
+
path: '/switches/arming-lock',
|
|
71
|
+
summary: 'Update arming lock switch',
|
|
72
|
+
description: 'Enables or disables the arming lock for a specific mode or globally.',
|
|
73
|
+
security: [{ BearerAuth: [] }],
|
|
74
|
+
request: {
|
|
75
|
+
body: {
|
|
76
|
+
content: {
|
|
77
|
+
'application/json': {
|
|
78
|
+
schema: ArmingLockRequestSchema,
|
|
79
|
+
example: { mode: 'home', value: true },
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
required: true,
|
|
83
|
+
},
|
|
84
|
+
},
|
|
85
|
+
responses: {
|
|
86
|
+
204: { description: 'Arming lock updated' },
|
|
87
|
+
...AUTH_RESPONSES,
|
|
88
|
+
409: {
|
|
89
|
+
content: { 'application/json': { schema: ErrorSchema } },
|
|
90
|
+
description: 'Arming lock update rejected by the system',
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
});
|
|
6
94
|
/** Hono HTTP server providing remote control of the security system. */
|
|
7
95
|
export class ServerService {
|
|
8
96
|
log;
|
|
@@ -11,7 +99,7 @@ export class ServerService {
|
|
|
11
99
|
stateHandler;
|
|
12
100
|
tripHandler;
|
|
13
101
|
switchHandler;
|
|
14
|
-
application = new
|
|
102
|
+
application = new OpenAPIHono();
|
|
15
103
|
constructor(log, options, state, stateHandler, tripHandler, switchHandler) {
|
|
16
104
|
this.log = log;
|
|
17
105
|
this.options = options;
|
|
@@ -28,113 +116,109 @@ export class ServerService {
|
|
|
28
116
|
this.log.error(String(error));
|
|
29
117
|
});
|
|
30
118
|
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
const authError = this.authenticate(context);
|
|
119
|
+
createAuthMiddleware() {
|
|
120
|
+
return async (c, next) => {
|
|
121
|
+
const authError = this.authenticate(c);
|
|
35
122
|
if (authError !== null) {
|
|
36
123
|
return authError;
|
|
37
124
|
}
|
|
38
|
-
|
|
125
|
+
await next();
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
registerRoutes() {
|
|
129
|
+
const auth = this.createAuthMiddleware();
|
|
130
|
+
// Scalar UI
|
|
131
|
+
this.application.get('/', Scalar({
|
|
132
|
+
url: '/openapi.json',
|
|
133
|
+
pageTitle: 'Homebridge Security System API',
|
|
134
|
+
defaultOpenAllTags: true,
|
|
135
|
+
}));
|
|
136
|
+
// Register Bearer auth security scheme for OpenAPI documentation
|
|
137
|
+
this.application.openAPIRegistry.registerComponent('securitySchemes', 'BearerAuth', {
|
|
138
|
+
type: 'http',
|
|
139
|
+
scheme: 'bearer',
|
|
140
|
+
description: 'API key configured via the server_api_key plugin option.',
|
|
141
|
+
});
|
|
142
|
+
// OpenAPI spec
|
|
143
|
+
this.application.doc('/openapi.json', {
|
|
144
|
+
openapi: '3.1.0',
|
|
145
|
+
info: {
|
|
146
|
+
title: 'Homebridge Security System API',
|
|
147
|
+
version: '1.0.0',
|
|
148
|
+
description: 'Remote control API for the Homebridge Security System plugin.',
|
|
149
|
+
},
|
|
150
|
+
});
|
|
151
|
+
// GET /status
|
|
152
|
+
this.application.use('/status', auth);
|
|
153
|
+
this.application.openapi(statusRoute, (c) => {
|
|
154
|
+
return c.json({
|
|
39
155
|
arming: this.state.isArming,
|
|
40
156
|
current_mode: stateToMode(this.state.currentState),
|
|
41
157
|
target_mode: stateToMode(this.state.targetState),
|
|
42
158
|
tripped: this.stateHandler.isTripping(),
|
|
43
159
|
});
|
|
44
160
|
});
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
}
|
|
50
|
-
const delay = this.parseDelay(context);
|
|
161
|
+
// PUT /mode
|
|
162
|
+
this.application.use('/mode', auth);
|
|
163
|
+
this.application.openapi(modeRoute, (c) => {
|
|
164
|
+
const { mode, delay = 0 } = c.req.valid('json');
|
|
51
165
|
let success;
|
|
52
|
-
if (
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
166
|
+
if (mode === 'triggered') {
|
|
167
|
+
if (delay > 0) {
|
|
168
|
+
success = this.tripHandler.updateTripSwitch(true, OriginType.EXTERNAL, false);
|
|
169
|
+
}
|
|
170
|
+
else {
|
|
171
|
+
if (this.state.currentState === SecurityState.OFF && !this.options.overrideOff) {
|
|
172
|
+
return c.json({ reason: 'Cannot trigger alarm while system is disarmed' }, 409);
|
|
173
|
+
}
|
|
174
|
+
this.stateHandler.setCurrentState(SecurityState.TRIGGERED, OriginType.EXTERNAL);
|
|
175
|
+
success = true;
|
|
58
176
|
}
|
|
59
|
-
this.stateHandler.setCurrentState(SecurityState.TRIGGERED, OriginType.EXTERNAL);
|
|
60
|
-
success = true;
|
|
61
|
-
}
|
|
62
|
-
return context.json({ error: !success });
|
|
63
|
-
});
|
|
64
|
-
this.application.get('/home', (context) => {
|
|
65
|
-
const authError = this.authenticate(context);
|
|
66
|
-
if (authError !== null) {
|
|
67
|
-
return authError;
|
|
68
|
-
}
|
|
69
|
-
const delay = this.parseDelay(context);
|
|
70
|
-
const success = this.stateHandler.updateTargetState(SecurityState.HOME, OriginType.EXTERNAL, delay);
|
|
71
|
-
return context.json({ error: !success });
|
|
72
|
-
});
|
|
73
|
-
this.application.get('/away', (context) => {
|
|
74
|
-
const authError = this.authenticate(context);
|
|
75
|
-
if (authError !== null) {
|
|
76
|
-
return authError;
|
|
77
177
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
return context.json({ error: !success });
|
|
81
|
-
});
|
|
82
|
-
this.application.get('/night', (context) => {
|
|
83
|
-
const authError = this.authenticate(context);
|
|
84
|
-
if (authError !== null) {
|
|
85
|
-
return authError;
|
|
178
|
+
else {
|
|
179
|
+
success = this.stateHandler.updateTargetState(MODE_TO_STATE[mode], OriginType.EXTERNAL, delay);
|
|
86
180
|
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
return context.json({ error: !success });
|
|
90
|
-
});
|
|
91
|
-
this.application.get('/off', (context) => {
|
|
92
|
-
const authError = this.authenticate(context);
|
|
93
|
-
if (authError !== null) {
|
|
94
|
-
return authError;
|
|
181
|
+
if (!success) {
|
|
182
|
+
return c.json({ reason: 'Mode change rejected by the system' }, 409);
|
|
95
183
|
}
|
|
96
|
-
|
|
97
|
-
return context.json({ error: !success });
|
|
184
|
+
return c.body(null, 204);
|
|
98
185
|
});
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
}
|
|
104
|
-
const mode = context.req.param('mode').toLowerCase();
|
|
105
|
-
const value = context.req.param('value').includes('on');
|
|
186
|
+
// PUT /switches/arming-lock
|
|
187
|
+
this.application.use('/switches/arming-lock', auth);
|
|
188
|
+
this.application.openapi(armingLockRoute, (c) => {
|
|
189
|
+
const { mode, value } = c.req.valid('json');
|
|
106
190
|
const success = this.switchHandler.updateArmingLock(mode, value);
|
|
107
|
-
|
|
191
|
+
if (!success) {
|
|
192
|
+
return c.json({ reason: 'Arming lock update rejected by the system' }, 409);
|
|
193
|
+
}
|
|
194
|
+
return c.body(null, 204);
|
|
108
195
|
});
|
|
109
196
|
}
|
|
110
197
|
/**
|
|
111
|
-
*
|
|
112
|
-
* or null
|
|
198
|
+
* Validates the Authorization: Bearer <key> header when serverApiKey is configured.
|
|
199
|
+
* Returns an error Response on failure, or null to allow the request through.
|
|
113
200
|
*/
|
|
114
201
|
authenticate(context) {
|
|
115
|
-
if (this.options.
|
|
202
|
+
if (this.options.serverApiKey === null) {
|
|
116
203
|
return null;
|
|
117
204
|
}
|
|
118
|
-
const
|
|
119
|
-
if (
|
|
205
|
+
const authHeader = context.req.header('Authorization');
|
|
206
|
+
if (authHeader === undefined || !authHeader.startsWith('Bearer ')) {
|
|
120
207
|
this.log.info('Code required (Server)');
|
|
121
|
-
return context.json({
|
|
208
|
+
return context.json({ reason: 'API key required. Use the Authorization: Bearer <key> header.' }, 401);
|
|
122
209
|
}
|
|
123
210
|
if (this.state.invalidCodeCount >= 5) {
|
|
124
211
|
this.log.info('Code blocked (Server)');
|
|
125
|
-
return context.json({
|
|
212
|
+
return context.json({ reason: 'API key blocked due to too many invalid attempts' }, 403);
|
|
126
213
|
}
|
|
127
|
-
|
|
214
|
+
const code = authHeader.slice('Bearer '.length).trim();
|
|
215
|
+
if (code !== this.options.serverApiKey) {
|
|
128
216
|
this.state.invalidCodeCount++;
|
|
129
217
|
this.log.info('Code invalid (Server)');
|
|
130
|
-
return context.json({
|
|
218
|
+
return context.json({ reason: 'API key invalid' }, 403);
|
|
131
219
|
}
|
|
132
220
|
this.state.invalidCodeCount = 0;
|
|
133
221
|
return null;
|
|
134
222
|
}
|
|
135
|
-
parseDelay(context) {
|
|
136
|
-
const rawValue = parseInt(context.req.query('delay') ?? '', 10);
|
|
137
|
-
return isNaN(rawValue) || rawValue < 0 ? 0 : rawValue;
|
|
138
|
-
}
|
|
139
223
|
}
|
|
140
224
|
//# sourceMappingURL=server-service.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server-service.js","sourceRoot":"","sources":["../../src/services/server-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"server-service.js","sourceRoot":"","sources":["../../src/services/server-service.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "homebridge-securitysystem",
|
|
3
3
|
"displayName": "Homebridge Security System",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"version": "
|
|
5
|
+
"version": "11.0.0-beta.2",
|
|
6
6
|
"description": "Homebridge plugin that creates a security system accessory that can be triggered by HomeKit sensors.",
|
|
7
7
|
"author": "MiguelRipoll23",
|
|
8
8
|
"license": "MIT",
|
|
@@ -36,8 +36,11 @@
|
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
38
|
"@hono/node-server": "^1.19.14",
|
|
39
|
+
"@hono/zod-openapi": "^1.3.0",
|
|
40
|
+
"@scalar/hono-api-reference": "^0.10.9",
|
|
39
41
|
"hono": "^4.12.14",
|
|
40
|
-
"node-persist": "^4.0.1"
|
|
42
|
+
"node-persist": "^4.0.1",
|
|
43
|
+
"zod": "^4.3.6"
|
|
41
44
|
},
|
|
42
45
|
"devDependencies": {
|
|
43
46
|
"@eslint/js": "^10.0.1",
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { z } from '@hono/zod-openapi';
|
|
2
|
+
|
|
3
|
+
export const ArmingLockRequestSchema = z
|
|
4
|
+
.object({
|
|
5
|
+
mode: z
|
|
6
|
+
.enum(['global', 'home', 'away', 'night'])
|
|
7
|
+
.openapi({ example: 'home', description: 'Arming lock mode to update' }),
|
|
8
|
+
value: z
|
|
9
|
+
.boolean()
|
|
10
|
+
.openapi({ example: true, description: 'True to enable the arming lock, false to disable it' }),
|
|
11
|
+
})
|
|
12
|
+
.openapi('ArmingLockRequest');
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { z } from '@hono/zod-openapi';
|
|
2
|
+
|
|
3
|
+
export const ModeRequestSchema = z
|
|
4
|
+
.object({
|
|
5
|
+
mode: z
|
|
6
|
+
.enum(['home', 'away', 'night', 'off', 'triggered'])
|
|
7
|
+
.openapi({ example: 'home', description: 'Target security mode to activate' }),
|
|
8
|
+
delay: z
|
|
9
|
+
.number()
|
|
10
|
+
.int()
|
|
11
|
+
.nonnegative()
|
|
12
|
+
.optional()
|
|
13
|
+
.openapi({
|
|
14
|
+
example: 5000,
|
|
15
|
+
description: 'Optional delay in milliseconds before applying the mode change',
|
|
16
|
+
}),
|
|
17
|
+
})
|
|
18
|
+
.openapi('ModeRequest');
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { z } from '@hono/zod-openapi';
|
|
2
|
+
|
|
3
|
+
export const StatusResponseSchema = z
|
|
4
|
+
.object({
|
|
5
|
+
arming: z.boolean().openapi({ example: false, description: 'Whether the system is currently arming' }),
|
|
6
|
+
current_mode: z.string().openapi({ example: 'off', description: 'The current active mode' }),
|
|
7
|
+
target_mode: z.string().openapi({ example: 'home', description: 'The target mode being transitioned to' }),
|
|
8
|
+
tripped: z.boolean().openapi({ example: false, description: 'Whether a trip switch is active' }),
|
|
9
|
+
})
|
|
10
|
+
.openapi('StatusResponse');
|
|
@@ -176,7 +176,8 @@ export class ConfigurationService {
|
|
|
176
176
|
|
|
177
177
|
// Server
|
|
178
178
|
serverPort: this.num(raw, 'server_port'),
|
|
179
|
-
|
|
179
|
+
// TODO: Remove serverCode fallback in future major version
|
|
180
|
+
serverApiKey: this.str(raw, 'server_api_key') ?? (this.num(raw, 'server_code') !== null ? String(this.num(raw, 'server_code')!) : null),
|
|
180
181
|
|
|
181
182
|
// Shell commands
|
|
182
183
|
commandTargetHome: this.str(raw, 'command_target_home'),
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { OpenAPIHono, createRoute } from '@hono/zod-openapi';
|
|
2
2
|
import { serve } from '@hono/node-server';
|
|
3
|
-
import
|
|
3
|
+
import { Scalar } from '@scalar/hono-api-reference';
|
|
4
|
+
import type { Context, MiddlewareHandler } from 'hono';
|
|
4
5
|
import type { Logging } from 'homebridge';
|
|
5
6
|
import { SecurityState } from '../types/security-state-type.js';
|
|
6
7
|
import { OriginType } from '../types/origin-type.js';
|
|
@@ -10,10 +11,104 @@ import type { SystemState } from '../interfaces/system-state-interface.js';
|
|
|
10
11
|
import type { StateHandler } from '../handlers/state-handler.js';
|
|
11
12
|
import type { TripHandler } from '../handlers/trip-handler.js';
|
|
12
13
|
import type { SwitchHandler } from '../handlers/switch-handler.js';
|
|
14
|
+
import { ErrorSchema } from '../schemas/error-schema.js';
|
|
15
|
+
import { StatusResponseSchema } from '../schemas/status-response-schema.js';
|
|
16
|
+
import { ModeRequestSchema } from '../schemas/mode-request-schema.js';
|
|
17
|
+
import { ArmingLockRequestSchema } from '../schemas/arming-lock-schema.js';
|
|
18
|
+
|
|
19
|
+
const MODE_TO_STATE: Record<string, SecurityState> = {
|
|
20
|
+
home: SecurityState.HOME,
|
|
21
|
+
away: SecurityState.AWAY,
|
|
22
|
+
night: SecurityState.NIGHT,
|
|
23
|
+
off: SecurityState.OFF,
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const AUTH_RESPONSES = {
|
|
27
|
+
401: {
|
|
28
|
+
content: { 'application/json': { schema: ErrorSchema } },
|
|
29
|
+
description: 'API key required',
|
|
30
|
+
},
|
|
31
|
+
403: {
|
|
32
|
+
content: { 'application/json': { schema: ErrorSchema } },
|
|
33
|
+
description: 'API key invalid or blocked',
|
|
34
|
+
},
|
|
35
|
+
} as const;
|
|
36
|
+
|
|
37
|
+
const statusRoute = createRoute({
|
|
38
|
+
method: 'get',
|
|
39
|
+
path: '/status',
|
|
40
|
+
summary: 'Get system status',
|
|
41
|
+
description:
|
|
42
|
+
'Returns the current arming state, active mode, target mode, and trip status of the security system.',
|
|
43
|
+
security: [{ BearerAuth: [] }],
|
|
44
|
+
responses: {
|
|
45
|
+
200: {
|
|
46
|
+
content: { 'application/json': { schema: StatusResponseSchema } },
|
|
47
|
+
description: 'Current system status',
|
|
48
|
+
},
|
|
49
|
+
...AUTH_RESPONSES,
|
|
50
|
+
},
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
const modeRoute = createRoute({
|
|
54
|
+
method: 'put',
|
|
55
|
+
path: '/mode',
|
|
56
|
+
summary: 'Change security mode',
|
|
57
|
+
description:
|
|
58
|
+
'Sets the target security mode. Supported modes: home, away, night, off, triggered. ' +
|
|
59
|
+
'Use "triggered" to activate the alarm. An optional delay (ms) defers the transition.',
|
|
60
|
+
security: [{ BearerAuth: [] }],
|
|
61
|
+
request: {
|
|
62
|
+
body: {
|
|
63
|
+
content: {
|
|
64
|
+
'application/json': {
|
|
65
|
+
schema: ModeRequestSchema,
|
|
66
|
+
example: { mode: 'home', delay: 5000 },
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
required: true,
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
responses: {
|
|
73
|
+
204: { description: 'Mode change accepted' },
|
|
74
|
+
...AUTH_RESPONSES,
|
|
75
|
+
409: {
|
|
76
|
+
content: { 'application/json': { schema: ErrorSchema } },
|
|
77
|
+
description: 'Mode change rejected by the system',
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
const armingLockRoute = createRoute({
|
|
83
|
+
method: 'put',
|
|
84
|
+
path: '/switches/arming-lock',
|
|
85
|
+
summary: 'Update arming lock switch',
|
|
86
|
+
description: 'Enables or disables the arming lock for a specific mode or globally.',
|
|
87
|
+
security: [{ BearerAuth: [] }],
|
|
88
|
+
request: {
|
|
89
|
+
body: {
|
|
90
|
+
content: {
|
|
91
|
+
'application/json': {
|
|
92
|
+
schema: ArmingLockRequestSchema,
|
|
93
|
+
example: { mode: 'home', value: true },
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
required: true,
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
responses: {
|
|
100
|
+
204: { description: 'Arming lock updated' },
|
|
101
|
+
...AUTH_RESPONSES,
|
|
102
|
+
409: {
|
|
103
|
+
content: { 'application/json': { schema: ErrorSchema } },
|
|
104
|
+
description: 'Arming lock update rejected by the system',
|
|
105
|
+
},
|
|
106
|
+
},
|
|
107
|
+
});
|
|
13
108
|
|
|
14
109
|
/** Hono HTTP server providing remote control of the security system. */
|
|
15
110
|
export class ServerService {
|
|
16
|
-
private readonly application = new
|
|
111
|
+
private readonly application = new OpenAPIHono();
|
|
17
112
|
|
|
18
113
|
constructor(
|
|
19
114
|
private readonly log: Logging,
|
|
@@ -38,18 +133,50 @@ export class ServerService {
|
|
|
38
133
|
});
|
|
39
134
|
}
|
|
40
135
|
|
|
41
|
-
private
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
);
|
|
45
|
-
|
|
46
|
-
this.application.get('/status', (context) => {
|
|
47
|
-
const authError = this.authenticate(context);
|
|
136
|
+
private createAuthMiddleware(): MiddlewareHandler {
|
|
137
|
+
return async (c, next) => {
|
|
138
|
+
const authError = this.authenticate(c);
|
|
48
139
|
if (authError !== null) {
|
|
49
140
|
return authError;
|
|
50
141
|
}
|
|
142
|
+
await next();
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
private registerRoutes(): void {
|
|
147
|
+
const auth = this.createAuthMiddleware();
|
|
148
|
+
|
|
149
|
+
// Scalar UI
|
|
150
|
+
this.application.get(
|
|
151
|
+
'/',
|
|
152
|
+
Scalar({
|
|
153
|
+
url: '/openapi.json',
|
|
154
|
+
pageTitle: 'Homebridge Security System API',
|
|
155
|
+
defaultOpenAllTags: true,
|
|
156
|
+
}),
|
|
157
|
+
);
|
|
51
158
|
|
|
52
|
-
|
|
159
|
+
// Register Bearer auth security scheme for OpenAPI documentation
|
|
160
|
+
this.application.openAPIRegistry.registerComponent('securitySchemes', 'BearerAuth', {
|
|
161
|
+
type: 'http',
|
|
162
|
+
scheme: 'bearer',
|
|
163
|
+
description: 'API key configured via the server_api_key plugin option.',
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
// OpenAPI spec
|
|
167
|
+
this.application.doc('/openapi.json', {
|
|
168
|
+
openapi: '3.1.0',
|
|
169
|
+
info: {
|
|
170
|
+
title: 'Homebridge Security System API',
|
|
171
|
+
version: '1.0.0',
|
|
172
|
+
description: 'Remote control API for the Homebridge Security System plugin.',
|
|
173
|
+
},
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
// GET /status
|
|
177
|
+
this.application.use('/status', auth);
|
|
178
|
+
this.application.openapi(statusRoute, (c) => {
|
|
179
|
+
return c.json({
|
|
53
180
|
arming: this.state.isArming,
|
|
54
181
|
current_mode: stateToMode(this.state.currentState),
|
|
55
182
|
target_mode: stateToMode(this.state.targetState),
|
|
@@ -57,120 +184,83 @@ export class ServerService {
|
|
|
57
184
|
});
|
|
58
185
|
});
|
|
59
186
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
const delay = this.parseDelay(context);
|
|
187
|
+
// PUT /mode
|
|
188
|
+
this.application.use('/mode', auth);
|
|
189
|
+
this.application.openapi(modeRoute, (c) => {
|
|
190
|
+
const { mode, delay = 0 } = c.req.valid('json');
|
|
67
191
|
let success: boolean;
|
|
68
192
|
|
|
69
|
-
if (
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
193
|
+
if (mode === 'triggered') {
|
|
194
|
+
if (delay > 0) {
|
|
195
|
+
success = this.tripHandler.updateTripSwitch(true, OriginType.EXTERNAL, false);
|
|
196
|
+
} else {
|
|
197
|
+
if (this.state.currentState === SecurityState.OFF && !this.options.overrideOff) {
|
|
198
|
+
return c.json({ reason: 'Cannot trigger alarm while system is disarmed' }, 409);
|
|
199
|
+
}
|
|
200
|
+
this.stateHandler.setCurrentState(SecurityState.TRIGGERED, OriginType.EXTERNAL);
|
|
201
|
+
success = true;
|
|
74
202
|
}
|
|
75
|
-
|
|
76
|
-
success =
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
return context.json({ error: !success });
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
this.application.get('/home', (context) => {
|
|
83
|
-
const authError = this.authenticate(context);
|
|
84
|
-
if (authError !== null) {
|
|
85
|
-
return authError;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
const delay = this.parseDelay(context);
|
|
89
|
-
const success = this.stateHandler.updateTargetState(SecurityState.HOME, OriginType.EXTERNAL, delay);
|
|
90
|
-
return context.json({ error: !success });
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
this.application.get('/away', (context) => {
|
|
94
|
-
const authError = this.authenticate(context);
|
|
95
|
-
if (authError !== null) {
|
|
96
|
-
return authError;
|
|
203
|
+
} else {
|
|
204
|
+
success = this.stateHandler.updateTargetState(MODE_TO_STATE[mode], OriginType.EXTERNAL, delay);
|
|
97
205
|
}
|
|
98
206
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
return context.json({ error: !success });
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
this.application.get('/night', (context) => {
|
|
105
|
-
const authError = this.authenticate(context);
|
|
106
|
-
if (authError !== null) {
|
|
107
|
-
return authError;
|
|
207
|
+
if (!success) {
|
|
208
|
+
return c.json({ reason: 'Mode change rejected by the system' }, 409);
|
|
108
209
|
}
|
|
109
210
|
|
|
110
|
-
|
|
111
|
-
const success = this.stateHandler.updateTargetState(SecurityState.NIGHT, OriginType.EXTERNAL, delay);
|
|
112
|
-
return context.json({ error: !success });
|
|
211
|
+
return c.body(null, 204);
|
|
113
212
|
});
|
|
114
213
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
const success = this.stateHandler.updateTargetState(SecurityState.OFF, OriginType.EXTERNAL, 0);
|
|
122
|
-
return context.json({ error: !success });
|
|
123
|
-
});
|
|
214
|
+
// PUT /switches/arming-lock
|
|
215
|
+
this.application.use('/switches/arming-lock', auth);
|
|
216
|
+
this.application.openapi(armingLockRoute, (c) => {
|
|
217
|
+
const { mode, value } = c.req.valid('json');
|
|
218
|
+
const success = this.switchHandler.updateArmingLock(mode, value);
|
|
124
219
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
if (authError !== null) {
|
|
128
|
-
return authError;
|
|
220
|
+
if (!success) {
|
|
221
|
+
return c.json({ reason: 'Arming lock update rejected by the system' }, 409);
|
|
129
222
|
}
|
|
130
223
|
|
|
131
|
-
|
|
132
|
-
const value = context.req.param('value').includes('on');
|
|
133
|
-
const success = this.switchHandler.updateArmingLock(mode, value);
|
|
134
|
-
return context.json({ error: !success });
|
|
224
|
+
return c.body(null, 204);
|
|
135
225
|
});
|
|
136
226
|
}
|
|
137
227
|
|
|
138
228
|
/**
|
|
139
|
-
*
|
|
140
|
-
* or null
|
|
229
|
+
* Validates the Authorization: Bearer <key> header when serverApiKey is configured.
|
|
230
|
+
* Returns an error Response on failure, or null to allow the request through.
|
|
141
231
|
*/
|
|
142
232
|
private authenticate(context: Context): Response | null {
|
|
143
|
-
if (this.options.
|
|
233
|
+
if (this.options.serverApiKey === null) {
|
|
144
234
|
return null;
|
|
145
235
|
}
|
|
146
236
|
|
|
147
|
-
const
|
|
237
|
+
const authHeader = context.req.header('Authorization');
|
|
148
238
|
|
|
149
|
-
if (
|
|
239
|
+
if (authHeader === undefined || !authHeader.startsWith('Bearer ')) {
|
|
150
240
|
this.log.info('Code required (Server)');
|
|
151
241
|
return context.json(
|
|
152
|
-
{
|
|
242
|
+
{ reason: 'API key required. Use the Authorization: Bearer <key> header.' },
|
|
153
243
|
401,
|
|
154
|
-
);
|
|
244
|
+
) as Response;
|
|
155
245
|
}
|
|
156
246
|
|
|
157
247
|
if (this.state.invalidCodeCount >= 5) {
|
|
158
248
|
this.log.info('Code blocked (Server)');
|
|
159
|
-
return context.json(
|
|
249
|
+
return context.json(
|
|
250
|
+
{ reason: 'API key blocked due to too many invalid attempts' },
|
|
251
|
+
403,
|
|
252
|
+
) as Response;
|
|
160
253
|
}
|
|
161
254
|
|
|
162
|
-
|
|
255
|
+
const code = authHeader.slice('Bearer '.length).trim();
|
|
256
|
+
|
|
257
|
+
if (code !== this.options.serverApiKey) {
|
|
163
258
|
this.state.invalidCodeCount++;
|
|
164
259
|
this.log.info('Code invalid (Server)');
|
|
165
|
-
return context.json({
|
|
260
|
+
return context.json({ reason: 'API key invalid' }, 403) as Response;
|
|
166
261
|
}
|
|
167
262
|
|
|
168
263
|
this.state.invalidCodeCount = 0;
|
|
169
264
|
return null;
|
|
170
265
|
}
|
|
171
|
-
|
|
172
|
-
private parseDelay(context: Context): number {
|
|
173
|
-
const rawValue = parseInt(context.req.query('delay') ?? '', 10);
|
|
174
|
-
return isNaN(rawValue) || rawValue < 0 ? 0 : rawValue;
|
|
175
|
-
}
|
|
176
266
|
}
|