@fastybird/smart-panel-backend 1.1.0-alpha.2 → 1.1.0-alpha.4
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/dist/common/filters/conflict-exception.filter.d.ts +6 -0
- package/dist/common/filters/conflict-exception.filter.js +59 -0
- package/dist/common/filters/conflict-exception.filter.js.map +1 -0
- package/dist/common/filters/global-error.filter.js +1 -4
- package/dist/common/filters/global-error.filter.js.map +1 -1
- package/dist/common/filters/global-filters.d.ts +3 -0
- package/dist/common/filters/global-filters.js +22 -0
- package/dist/common/filters/global-filters.js.map +1 -0
- package/dist/common/filters/unprocessable-entity-exception.filter.d.ts +1 -0
- package/dist/common/filters/unprocessable-entity-exception.filter.js +15 -3
- package/dist/common/filters/unprocessable-entity-exception.filter.js.map +1 -1
- package/dist/common/utils/transform.utils.js +3 -0
- package/dist/common/utils/transform.utils.js.map +1 -1
- package/dist/main.js +2 -7
- package/dist/main.js.map +1 -1
- package/dist/modules/platform/services/platform.service.d.ts +13 -4
- package/dist/modules/platform/services/platform.service.js +57 -35
- package/dist/modules/platform/services/platform.service.js.map +1 -1
- package/dist/modules/remote-access/dto/update-config.dto.js +5 -0
- package/dist/modules/remote-access/dto/update-config.dto.js.map +1 -1
- package/dist/modules/remote-access/validators/is-remote-access-url.validator.js +5 -2
- package/dist/modules/remote-access/validators/is-remote-access-url.validator.js.map +1 -1
- package/dist/modules/system/services/privileged-worker.service.d.ts +10 -0
- package/dist/modules/system/services/privileged-worker.service.js +137 -11
- package/dist/modules/system/services/privileged-worker.service.js.map +1 -1
- package/dist/plugins/devices-shelly-ng/delegates/delegates-manager.service.d.ts +2 -0
- package/dist/plugins/devices-shelly-ng/delegates/delegates-manager.service.js +143 -102
- package/dist/plugins/devices-shelly-ng/delegates/delegates-manager.service.js.map +1 -1
- package/dist/plugins/devices-shelly-ng/delegates/shelly-device.delegate.d.ts +4 -0
- package/dist/plugins/devices-shelly-ng/delegates/shelly-device.delegate.js +18 -1
- package/dist/plugins/devices-shelly-ng/delegates/shelly-device.delegate.js.map +1 -1
- package/dist/plugins/devices-shelly-ng/devices-shelly-ng.constants.js +8 -11
- package/dist/plugins/devices-shelly-ng/devices-shelly-ng.constants.js.map +1 -1
- package/dist/plugins/devices-shelly-ng/mappings/mapping-loader.service.js +4 -0
- package/dist/plugins/devices-shelly-ng/mappings/mapping-loader.service.js.map +1 -1
- package/dist/plugins/devices-shelly-ng/services/shelly-ws-server.service.d.ts +0 -1
- package/dist/plugins/devices-shelly-ng/services/shelly-ws-server.service.js +7 -12
- package/dist/plugins/devices-shelly-ng/services/shelly-ws-server.service.js.map +1 -1
- package/dist/plugins/devices-shelly-ng/utils/transform.utils.d.ts +2 -0
- package/dist/plugins/devices-shelly-ng/utils/transform.utils.js +14 -1
- package/dist/plugins/devices-shelly-ng/utils/transform.utils.js.map +1 -1
- package/dist/plugins/remote-access-tailscale/controllers/setup.controller.d.ts +1 -0
- package/dist/plugins/remote-access-tailscale/controllers/setup.controller.js +26 -10
- package/dist/plugins/remote-access-tailscale/controllers/setup.controller.js.map +1 -1
- package/dist/plugins/remote-access-tailscale/controllers/status.controller.d.ts +6 -1
- package/dist/plugins/remote-access-tailscale/controllers/status.controller.js +28 -3
- package/dist/plugins/remote-access-tailscale/controllers/status.controller.js.map +1 -1
- package/dist/plugins/remote-access-tailscale/models/status.model.d.ts +19 -0
- package/dist/plugins/remote-access-tailscale/models/status.model.js +158 -1
- package/dist/plugins/remote-access-tailscale/models/status.model.js.map +1 -1
- package/dist/plugins/remote-access-tailscale/remote-access-tailscale.exceptions.d.ts +13 -0
- package/dist/plugins/remote-access-tailscale/remote-access-tailscale.exceptions.js +27 -0
- package/dist/plugins/remote-access-tailscale/remote-access-tailscale.exceptions.js.map +1 -0
- package/dist/plugins/remote-access-tailscale/remote-access-tailscale.openapi.d.ts +2 -2
- package/dist/plugins/remote-access-tailscale/remote-access-tailscale.openapi.js +2 -0
- package/dist/plugins/remote-access-tailscale/remote-access-tailscale.openapi.js.map +1 -1
- package/dist/plugins/remote-access-tailscale/remote-access-tailscale.plugin.js +1 -1
- package/dist/plugins/remote-access-tailscale/scripts/tailscale-setup.sh +61 -0
- package/dist/plugins/remote-access-tailscale/services/tailscale-cli.service.d.ts +9 -0
- package/dist/plugins/remote-access-tailscale/services/tailscale-cli.service.js +12 -0
- package/dist/plugins/remote-access-tailscale/services/tailscale-cli.service.js.map +1 -1
- package/dist/plugins/remote-access-tailscale/services/tailscale-login.service.d.ts +1 -0
- package/dist/plugins/remote-access-tailscale/services/tailscale-login.service.js +23 -2
- package/dist/plugins/remote-access-tailscale/services/tailscale-login.service.js.map +1 -1
- package/dist/plugins/remote-access-tailscale/services/tailscale-node-managed.service.d.ts +26 -0
- package/dist/plugins/remote-access-tailscale/services/tailscale-node-managed.service.js +245 -29
- package/dist/plugins/remote-access-tailscale/services/tailscale-node-managed.service.js.map +1 -1
- package/dist/plugins/remote-access-tailscale/services/tailscale-serve.service.d.ts +8 -3
- package/dist/plugins/remote-access-tailscale/services/tailscale-serve.service.js +39 -12
- package/dist/plugins/remote-access-tailscale/services/tailscale-serve.service.js.map +1 -1
- package/dist/plugins/remote-access-tailscale/services/tailscale-setup.service.d.ts +14 -5
- package/dist/plugins/remote-access-tailscale/services/tailscale-setup.service.js +51 -16
- package/dist/plugins/remote-access-tailscale/services/tailscale-setup.service.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +2 -2
|
@@ -19,15 +19,30 @@ let TailscaleServeService = class TailscaleServeService {
|
|
|
19
19
|
this.cli = cli;
|
|
20
20
|
this.logger = (0, logger_1.createExtensionLogger)(remote_access_tailscale_constants_1.REMOTE_ACCESS_TAILSCALE_PLUGIN_NAME, 'TailscaleServeService');
|
|
21
21
|
}
|
|
22
|
-
async
|
|
23
|
-
const
|
|
24
|
-
const hasHttpsCap = Object.hasOwn(capMap, 'https');
|
|
25
|
-
const hasFunnelCap = Object.hasOwn(capMap, 'funnel');
|
|
26
|
-
const dnsName = this.stripTrailingDot(status.Self?.DNSName);
|
|
27
|
-
const desired = this.desiredState(config, hasHttpsCap, hasFunnelCap);
|
|
22
|
+
async read(config, port, status) {
|
|
23
|
+
const { hasHttpsCap, hasFunnelCap, dnsName } = this.readCaps(status);
|
|
28
24
|
const { serveActive, funnelActive } = dnsName
|
|
29
|
-
? await this.
|
|
25
|
+
? await this.readHandlerState(`${dnsName}:443`, `http://127.0.0.1:${port}`)
|
|
30
26
|
: { serveActive: false, funnelActive: false };
|
|
27
|
+
return this.buildResult(config, hasHttpsCap, hasFunnelCap, dnsName, serveActive, funnelActive, false);
|
|
28
|
+
}
|
|
29
|
+
async converge(config, port, status) {
|
|
30
|
+
const { hasHttpsCap, hasFunnelCap, dnsName } = this.readCaps(status);
|
|
31
|
+
const desired = this.desiredState(config, hasHttpsCap, hasFunnelCap);
|
|
32
|
+
const { serveActive, funnelActive, permissionDenied } = dnsName
|
|
33
|
+
? await this.convergeHandler(desired, port, `${dnsName}:443`, `http://127.0.0.1:${port}`)
|
|
34
|
+
: { serveActive: false, funnelActive: false, permissionDenied: false };
|
|
35
|
+
return this.buildResult(config, hasHttpsCap, hasFunnelCap, dnsName, serveActive, funnelActive, permissionDenied);
|
|
36
|
+
}
|
|
37
|
+
readCaps(status) {
|
|
38
|
+
const capMap = status.Self?.CapMap ?? {};
|
|
39
|
+
return {
|
|
40
|
+
hasHttpsCap: Object.hasOwn(capMap, 'https'),
|
|
41
|
+
hasFunnelCap: Object.hasOwn(capMap, 'funnel'),
|
|
42
|
+
dnsName: this.stripTrailingDot(status.Self?.DNSName),
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
buildResult(config, hasHttpsCap, hasFunnelCap, dnsName, serveActive, funnelActive, permissionDenied) {
|
|
31
46
|
const endpoints = [];
|
|
32
47
|
const proxyAddresses = [];
|
|
33
48
|
if (serveActive && dnsName) {
|
|
@@ -61,7 +76,7 @@ let TailscaleServeService = class TailscaleServeService {
|
|
|
61
76
|
message: 'This node is publicly reachable through Tailscale Funnel. The Smart Panel login is the only gate — multi-factor authentication is not available.',
|
|
62
77
|
});
|
|
63
78
|
}
|
|
64
|
-
return { endpoints, proxyAddresses, advisories };
|
|
79
|
+
return { endpoints, proxyAddresses, advisories, permissionDenied };
|
|
65
80
|
}
|
|
66
81
|
desiredState(config, hasHttpsCap, hasFunnelCap) {
|
|
67
82
|
if (!config.serveHttps || !hasHttpsCap) {
|
|
@@ -75,9 +90,17 @@ let TailscaleServeService = class TailscaleServeService {
|
|
|
75
90
|
}
|
|
76
91
|
return funnelActive ? 'public' : 'private';
|
|
77
92
|
}
|
|
78
|
-
async
|
|
93
|
+
async readHandlerState(hostPort, targetUrl) {
|
|
94
|
+
const serveStatus = await this.readServeStatus();
|
|
95
|
+
return {
|
|
96
|
+
serveActive: this.isServeActive(serveStatus, hostPort, targetUrl),
|
|
97
|
+
funnelActive: this.isFunnelActive(serveStatus, hostPort),
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
async convergeHandler(desired, port, hostPort, targetUrl) {
|
|
79
101
|
let serveStatus = await this.readServeStatus();
|
|
80
102
|
let current = this.currentState(this.isServeActive(serveStatus, hostPort, targetUrl), this.isFunnelActive(serveStatus, hostPort));
|
|
103
|
+
let permissionDenied = false;
|
|
81
104
|
if (current !== desired) {
|
|
82
105
|
try {
|
|
83
106
|
if (desired === 'off') {
|
|
@@ -93,14 +116,18 @@ let TailscaleServeService = class TailscaleServeService {
|
|
|
93
116
|
current = this.currentState(this.isServeActive(serveStatus, hostPort, targetUrl), this.isFunnelActive(serveStatus, hostPort));
|
|
94
117
|
}
|
|
95
118
|
catch (error) {
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
119
|
+
permissionDenied = error instanceof tailscale_cli_service_1.TailscaleCliError && error.kind === 'permission-denied';
|
|
120
|
+
if (!permissionDenied) {
|
|
121
|
+
this.logger.warn(`Failed to apply the Tailscale Serve/Funnel handler (wanted "${desired}")`, {
|
|
122
|
+
message: error instanceof Error ? error.message : String(error),
|
|
123
|
+
});
|
|
124
|
+
}
|
|
99
125
|
}
|
|
100
126
|
}
|
|
101
127
|
return {
|
|
102
128
|
serveActive: current !== 'off',
|
|
103
129
|
funnelActive: current === 'public',
|
|
130
|
+
permissionDenied,
|
|
104
131
|
};
|
|
105
132
|
}
|
|
106
133
|
async readServeStatus() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tailscale-serve.service.js","sourceRoot":"","sources":["../../../../src/plugins/remote-access-tailscale/services/tailscale-serve.service.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAA4C;AAE5C,mDAA+D;AAM/D,4FAA2F;AAE3F,
|
|
1
|
+
{"version":3,"file":"tailscale-serve.service.js","sourceRoot":"","sources":["../../../../src/plugins/remote-access-tailscale/services/tailscale-serve.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
import { ConfigService as NestConfigService } from '@nestjs/config';
|
|
2
2
|
import { EventEmitter2 } from '@nestjs/event-emitter';
|
|
3
|
+
import { ConfigService } from '../../../modules/config/services/config.service';
|
|
4
|
+
import { ManagedServiceManagerService } from '../../../modules/extensions/services/managed-service-manager.service';
|
|
3
5
|
import { PlatformService } from '../../../modules/platform/services/platform.service';
|
|
4
6
|
import { PrivilegedJobStatus, PrivilegedWorkerService } from '../../../modules/system/services/privileged-worker.service';
|
|
7
|
+
import { TailscaleSetupUnavailableException } from '../remote-access-tailscale.exceptions';
|
|
5
8
|
import { TailscaleNodeManagedService } from './tailscale-node-managed.service';
|
|
9
|
+
export { TailscaleSetupUnavailableException };
|
|
6
10
|
export interface TailscaleSetupProgressEvent {
|
|
7
11
|
type: string;
|
|
8
12
|
job: string;
|
|
@@ -10,21 +14,26 @@ export interface TailscaleSetupProgressEvent {
|
|
|
10
14
|
state: PrivilegedJobStatus['state'];
|
|
11
15
|
message?: string;
|
|
12
16
|
}
|
|
13
|
-
export declare class TailscaleSetupUnavailableException extends Error {
|
|
14
|
-
constructor(message: string);
|
|
15
|
-
}
|
|
16
17
|
export declare class TailscaleSetupService {
|
|
17
18
|
private readonly privilegedWorker;
|
|
18
19
|
private readonly nestConfigService;
|
|
19
20
|
private readonly nodeManagedService;
|
|
20
21
|
private readonly eventEmitter;
|
|
21
22
|
private readonly platformService;
|
|
23
|
+
private readonly configService;
|
|
24
|
+
private readonly managedServiceManager;
|
|
22
25
|
private readonly logger;
|
|
23
|
-
|
|
26
|
+
private lastJob;
|
|
27
|
+
constructor(privilegedWorker: PrivilegedWorkerService, nestConfigService: NestConfigService, nodeManagedService: TailscaleNodeManagedService, eventEmitter: EventEmitter2, platformService: PlatformService, configService: ConfigService, managedServiceManager: ManagedServiceManagerService);
|
|
24
28
|
install(): Promise<{
|
|
25
29
|
id: string;
|
|
26
30
|
}>;
|
|
31
|
+
getLastJob(): {
|
|
32
|
+
id: string;
|
|
33
|
+
status: PrivilegedJobStatus;
|
|
34
|
+
} | null;
|
|
27
35
|
private watchJob;
|
|
28
|
-
private
|
|
36
|
+
private onSetupComplete;
|
|
37
|
+
private refreshNodeRequirements;
|
|
29
38
|
private ensureDir;
|
|
30
39
|
}
|
|
@@ -21,35 +21,39 @@ const config_1 = require("@nestjs/config");
|
|
|
21
21
|
const event_emitter_1 = require("@nestjs/event-emitter");
|
|
22
22
|
const logger_1 = require("../../../common/logger");
|
|
23
23
|
const config_utils_1 = require("../../../common/utils/config.utils");
|
|
24
|
+
const config_service_1 = require("../../../modules/config/services/config.service");
|
|
25
|
+
const managed_service_manager_service_1 = require("../../../modules/extensions/services/managed-service-manager.service");
|
|
24
26
|
const platform_service_1 = require("../../../modules/platform/services/platform.service");
|
|
25
27
|
const remote_access_constants_1 = require("../../../modules/remote-access/remote-access.constants");
|
|
26
28
|
const privileged_worker_service_1 = require("../../../modules/system/services/privileged-worker.service");
|
|
27
29
|
const remote_access_tailscale_constants_1 = require("../remote-access-tailscale.constants");
|
|
30
|
+
const remote_access_tailscale_exceptions_1 = require("../remote-access-tailscale.exceptions");
|
|
31
|
+
Object.defineProperty(exports, "TailscaleSetupUnavailableException", { enumerable: true, get: function () { return remote_access_tailscale_exceptions_1.TailscaleSetupUnavailableException; } });
|
|
28
32
|
const tailscale_node_managed_service_1 = require("./tailscale-node-managed.service");
|
|
29
|
-
class TailscaleSetupUnavailableException extends Error {
|
|
30
|
-
constructor(message) {
|
|
31
|
-
super(message);
|
|
32
|
-
this.name = 'TailscaleSetupUnavailableException';
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
exports.TailscaleSetupUnavailableException = TailscaleSetupUnavailableException;
|
|
36
33
|
let TailscaleSetupService = class TailscaleSetupService {
|
|
37
|
-
constructor(privilegedWorker, nestConfigService, nodeManagedService, eventEmitter, platformService) {
|
|
34
|
+
constructor(privilegedWorker, nestConfigService, nodeManagedService, eventEmitter, platformService, configService, managedServiceManager) {
|
|
38
35
|
this.privilegedWorker = privilegedWorker;
|
|
39
36
|
this.nestConfigService = nestConfigService;
|
|
40
37
|
this.nodeManagedService = nodeManagedService;
|
|
41
38
|
this.eventEmitter = eventEmitter;
|
|
42
39
|
this.platformService = platformService;
|
|
40
|
+
this.configService = configService;
|
|
41
|
+
this.managedServiceManager = managedServiceManager;
|
|
43
42
|
this.logger = (0, logger_1.createExtensionLogger)(remote_access_tailscale_constants_1.REMOTE_ACCESS_TAILSCALE_PLUGIN_NAME, 'TailscaleSetupService');
|
|
43
|
+
this.lastJob = null;
|
|
44
44
|
}
|
|
45
45
|
async install() {
|
|
46
46
|
const allowDev = (0, config_utils_1.getEnvValue)(this.nestConfigService, remote_access_tailscale_constants_1.REMOTE_ACCESS_TAILSCALE_ALLOW_DEV_ENV, false);
|
|
47
47
|
if (allowDev) {
|
|
48
|
-
throw new TailscaleSetupUnavailableException(`Tailscale setup is unavailable while ${remote_access_tailscale_constants_1.REMOTE_ACCESS_TAILSCALE_ALLOW_DEV_ENV} is set. Prepare tailscale manually on the development platform: install it, run tailscaled, and grant the current user as operator
|
|
48
|
+
throw new remote_access_tailscale_exceptions_1.TailscaleSetupUnavailableException(`Tailscale setup is unavailable while ${remote_access_tailscale_constants_1.REMOTE_ACCESS_TAILSCALE_ALLOW_DEV_ENV} is set. Prepare tailscale manually on the development platform: install it, run tailscaled, and grant the current user as operator.`, 'platform-unsupported');
|
|
49
49
|
}
|
|
50
|
-
const
|
|
51
|
-
if (!
|
|
52
|
-
|
|
50
|
+
const privilegedWorkerSupport = await this.platformService.getPrivilegedWorkerSupport();
|
|
51
|
+
if (!privilegedWorkerSupport.supported) {
|
|
52
|
+
if (!this.platformService.isPlatformCapableOfPrivilegedWorkers()) {
|
|
53
|
+
throw new remote_access_tailscale_exceptions_1.TailscaleSetupUnavailableException(`Tailscale setup requires a platform with privileged-worker support; the '${this.platformService.getPlatformType()}' platform does not have it.`, 'platform-unsupported');
|
|
54
|
+
}
|
|
55
|
+
const reason = privilegedWorkerSupport.reason ?? 'Privileged jobs are currently unavailable on this installation.';
|
|
56
|
+
throw new remote_access_tailscale_exceptions_1.TailscaleSetupUnavailableException(`${reason} Re-run \`sudo smart-panel-service install\`, or add the sudoers grant from the installation guide.`, 'privileged-worker-unavailable');
|
|
53
57
|
}
|
|
54
58
|
const dataDir = (0, config_utils_1.getEnvValue)(this.nestConfigService, 'FB_DATA_DIR', '/var/lib/smart-panel');
|
|
55
59
|
const remoteAccessDir = (0, path_1.join)(dataDir, remote_access_tailscale_constants_1.TAILSCALE_DATA_SUBDIR);
|
|
@@ -73,11 +77,21 @@ let TailscaleSetupService = class TailscaleSetupService {
|
|
|
73
77
|
statusFile,
|
|
74
78
|
});
|
|
75
79
|
this.logger.log(`Tailscale setup job spawned (job: ${id})`);
|
|
80
|
+
const initialStatus = this.privilegedWorker.getStatus(id) ?? {
|
|
81
|
+
id,
|
|
82
|
+
state: 'running',
|
|
83
|
+
updatedAt: new Date().toISOString(),
|
|
84
|
+
};
|
|
85
|
+
this.lastJob = { id, status: initialStatus };
|
|
76
86
|
this.watchJob(id);
|
|
77
87
|
return { id };
|
|
78
88
|
}
|
|
89
|
+
getLastJob() {
|
|
90
|
+
return this.lastJob;
|
|
91
|
+
}
|
|
79
92
|
watchJob(id) {
|
|
80
93
|
const unsubscribe = this.privilegedWorker.onStatus(id, (status) => {
|
|
94
|
+
this.lastJob = { id, status };
|
|
81
95
|
const event = {
|
|
82
96
|
type: remote_access_tailscale_constants_1.REMOTE_ACCESS_TAILSCALE_PLUGIN_NAME,
|
|
83
97
|
job: id,
|
|
@@ -91,7 +105,7 @@ let TailscaleSetupService = class TailscaleSetupService {
|
|
|
91
105
|
}
|
|
92
106
|
if (status.state === 'complete') {
|
|
93
107
|
this.logger.log(`Tailscale setup job completed (job: ${id})`);
|
|
94
|
-
void this.
|
|
108
|
+
void this.onSetupComplete();
|
|
95
109
|
}
|
|
96
110
|
else {
|
|
97
111
|
this.logger.error(`Tailscale setup job did not complete (job: ${id}, state: ${status.state})`, {
|
|
@@ -102,15 +116,34 @@ let TailscaleSetupService = class TailscaleSetupService {
|
|
|
102
116
|
unsubscribe();
|
|
103
117
|
});
|
|
104
118
|
}
|
|
105
|
-
async
|
|
119
|
+
async onSetupComplete() {
|
|
106
120
|
try {
|
|
107
|
-
await this.
|
|
121
|
+
await this.refreshNodeRequirements();
|
|
108
122
|
}
|
|
109
123
|
catch (error) {
|
|
110
124
|
this.logger.warn('Failed to refresh Tailscale requirements after setup', {
|
|
111
125
|
message: error instanceof Error ? error.message : String(error),
|
|
112
126
|
});
|
|
113
127
|
}
|
|
128
|
+
try {
|
|
129
|
+
const pluginConfig = this.configService.getPluginConfig(remote_access_tailscale_constants_1.REMOTE_ACCESS_TAILSCALE_PLUGIN_NAME);
|
|
130
|
+
if (pluginConfig.enabled) {
|
|
131
|
+
await this.managedServiceManager.restartService('plugin', remote_access_tailscale_constants_1.REMOTE_ACCESS_TAILSCALE_PLUGIN_NAME, 'node');
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
catch (error) {
|
|
135
|
+
this.logger.warn('Failed to restart the Tailscale node service after setup', {
|
|
136
|
+
message: error instanceof Error ? error.message : String(error),
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
async refreshNodeRequirements() {
|
|
141
|
+
const nodeManagedService = this.nodeManagedService;
|
|
142
|
+
if (typeof nodeManagedService.refreshRequirements === 'function') {
|
|
143
|
+
await nodeManagedService.refreshRequirements('setup-complete');
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
await this.nodeManagedService.evaluateRequirements();
|
|
114
147
|
}
|
|
115
148
|
ensureDir(dir) {
|
|
116
149
|
if (!(0, fs_1.existsSync)(dir)) {
|
|
@@ -125,6 +158,8 @@ exports.TailscaleSetupService = TailscaleSetupService = __decorate([
|
|
|
125
158
|
config_1.ConfigService,
|
|
126
159
|
tailscale_node_managed_service_1.TailscaleNodeManagedService,
|
|
127
160
|
event_emitter_1.EventEmitter2,
|
|
128
|
-
platform_service_1.PlatformService
|
|
161
|
+
platform_service_1.PlatformService,
|
|
162
|
+
config_service_1.ConfigService,
|
|
163
|
+
managed_service_manager_service_1.ManagedServiceManagerService])
|
|
129
164
|
], TailscaleSetupService);
|
|
130
165
|
//# sourceMappingURL=tailscale-setup.service.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tailscale-setup.service.js","sourceRoot":"","sources":["../../../../src/plugins/remote-access-tailscale/services/tailscale-setup.service.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,2BAA2C;AAC3C,4CAAoB;AACpB,+BAA4B;AAE5B,2CAA4C;AAC5C,2CAAoE;AACpE,yDAAsD;AAEtD,mDAA+D;AAC/D,qEAAiE;AACjE,0FAAsF;AACtF,oGAA4G;AAC5G,0GAGoE;
|
|
1
|
+
{"version":3,"file":"tailscale-setup.service.js","sourceRoot":"","sources":["../../../../src/plugins/remote-access-tailscale/services/tailscale-setup.service.ts"],"names":[],"mappings":"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"}
|