Skip to content

Commit d595a1d

Browse files
committed
feat: expose totpEnabled status and pass TOTP token through sync setup
1 parent 6004f35 commit d595a1d

4 files changed

Lines changed: 55 additions & 19 deletions

File tree

apps/server/src/routes/api/setup.ts

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,19 @@
1-
"use strict";
21

3-
import sqlInit from "../../services/sql_init.js";
4-
import setupService from "../../services/setup.js";
5-
import log from "../../services/log.js";
6-
import appInfo from "../../services/app_info.js";
2+
73
import type { Request } from "express";
84

5+
import appInfo from "../../services/app_info.js";
6+
import log from "../../services/log.js";
7+
import setupService from "../../services/setup.js";
8+
import sqlInit from "../../services/sql_init.js";
9+
import totp from "../../services/totp.js";
10+
911
function getStatus() {
1012
return {
1113
isInitialized: sqlInit.isDbInitialized(),
1214
schemaExists: sqlInit.schemaExists(),
13-
syncVersion: appInfo.syncVersion
15+
syncVersion: appInfo.syncVersion,
16+
totpEnabled: totp.isTotpEnabled()
1417
};
1518
}
1619

@@ -19,9 +22,9 @@ async function setupNewDocument() {
1922
}
2023

2124
function setupSyncFromServer(req: Request) {
22-
const { syncServerHost, syncProxy, password } = req.body;
25+
const { syncServerHost, syncProxy, password, totpToken } = req.body;
2326

24-
return setupService.setupSyncFromSyncServer(syncServerHost, syncProxy, password);
27+
return setupService.setupSyncFromSyncServer(syncServerHost, syncProxy, password, totpToken);
2528
}
2629

2730
function saveSyncSeed(req: Request) {
@@ -82,10 +85,26 @@ function getSyncSeed() {
8285
};
8386
}
8487

88+
async function checkServerTotpStatus(req: Request) {
89+
const { syncServerHost } = req.body;
90+
91+
if (!syncServerHost) {
92+
return { totpEnabled: false };
93+
}
94+
95+
try {
96+
const resp = await setupService.checkRemoteTotpStatus(syncServerHost);
97+
return { totpEnabled: !!resp.totpEnabled };
98+
} catch {
99+
return { totpEnabled: false };
100+
}
101+
}
102+
85103
export default {
86104
getStatus,
87105
setupNewDocument,
88106
setupSyncFromServer,
89107
getSyncSeed,
90-
saveSyncSeed
108+
saveSyncSeed,
109+
checkServerTotpStatus
91110
};

apps/server/src/routes/routes.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,7 @@ function register(app: express.Application) {
244244
asyncRoute(PST, "/api/setup/sync-from-server", [auth.checkAppNotInitialized], setupApiRoute.setupSyncFromServer, apiResultHandler);
245245
route(GET, "/api/setup/sync-seed", [loginRateLimiter, auth.checkCredentials], setupApiRoute.getSyncSeed, apiResultHandler);
246246
asyncRoute(PST, "/api/setup/sync-seed", [auth.checkAppNotInitialized], setupApiRoute.saveSyncSeed, apiResultHandler);
247+
asyncRoute(PST, "/api/setup/check-server-totp", [auth.checkAppNotInitialized], setupApiRoute.checkServerTotpStatus, apiResultHandler);
247248

248249
apiRoute(GET, "/api/autocomplete", autocompleteApiRoute.getAutocomplete);
249250
apiRoute(GET, "/api/autocomplete/notesCount", autocompleteApiRoute.getNotesCount);

apps/server/src/services/api-interface.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import type { OptionRow } from "@triliumnext/commons";
66
export interface SetupStatusResponse {
77
syncVersion: number;
88
schemaExists: boolean;
9+
totpEnabled: boolean;
910
}
1011

1112
/**

apps/server/src/services/setup.ts

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
import syncService from "./sync.js";
1+
import becca from "../becca/becca.js";
2+
import type { SetupStatusResponse, SetupSyncSeedResponse } from "./api-interface.js";
3+
import appInfo from "./app_info.js";
24
import log from "./log.js";
3-
import sqlInit from "./sql_init.js";
45
import optionService from "./options.js";
5-
import syncOptions from "./sync_options.js";
66
import request from "./request.js";
7-
import appInfo from "./app_info.js";
7+
import sqlInit from "./sql_init.js";
8+
import syncService from "./sync.js";
9+
import syncOptions from "./sync_options.js";
810
import { timeLimit } from "./utils.js";
9-
import becca from "../becca/becca.js";
10-
import type { SetupStatusResponse, SetupSyncSeedResponse } from "./api-interface.js";
1111

1212
async function hasSyncServerSchemaAndSeed() {
1313
const response = await requestToSyncServer<SetupStatusResponse>("GET", "/api/setup/status");
@@ -55,13 +55,13 @@ async function requestToSyncServer<T>(method: string, path: string, body?: strin
5555
url: syncOptions.getSyncServerHost() + path,
5656
body,
5757
proxy: syncOptions.getSyncProxy(),
58-
timeout: timeout
58+
timeout
5959
}),
6060
timeout
6161
)) as T;
6262
}
6363

64-
async function setupSyncFromSyncServer(syncServerHost: string, syncProxy: string, password: string) {
64+
async function setupSyncFromSyncServer(syncServerHost: string, syncProxy: string, password: string, totpToken?: string) {
6565
if (sqlInit.isDbInitialized()) {
6666
return {
6767
result: "failure",
@@ -76,7 +76,7 @@ async function setupSyncFromSyncServer(syncServerHost: string, syncProxy: string
7676
const resp = await request.exec<SetupSyncSeedResponse>({
7777
method: "get",
7878
url: `${syncServerHost}/api/setup/sync-seed`,
79-
auth: { password },
79+
auth: { password, totpToken },
8080
proxy: syncProxy,
8181
timeout: 30000 // seed request should not take long
8282
});
@@ -111,10 +111,25 @@ function getSyncSeedOptions() {
111111
return [becca.getOption("documentId"), becca.getOption("documentSecret")];
112112
}
113113

114+
async function checkRemoteTotpStatus(syncServerHost: string): Promise<{ totpEnabled: boolean }> {
115+
try {
116+
const resp = await request.exec<{ totpEnabled?: boolean }>({
117+
method: "get",
118+
url: `${syncServerHost}/api/setup/status`,
119+
proxy: null,
120+
timeout: 10000
121+
});
122+
return { totpEnabled: !!resp?.totpEnabled };
123+
} catch {
124+
return { totpEnabled: false };
125+
}
126+
}
127+
114128
export default {
115129
hasSyncServerSchemaAndSeed,
116130
triggerSync,
117131
sendSeedToSyncServer,
118132
setupSyncFromSyncServer,
119-
getSyncSeedOptions
133+
getSyncSeedOptions,
134+
checkRemoteTotpStatus
120135
};

0 commit comments

Comments
 (0)