@kodelyth/nextcloud-talk 2026.5.42 → 2026.6.1
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/klaw.plugin.json +799 -2
- package/package.json +16 -4
- package/api.ts +0 -1
- package/channel-plugin-api.ts +0 -1
- package/contract-api.ts +0 -4
- package/doctor-contract-api.ts +0 -1
- package/index.ts +0 -20
- package/runtime-api.ts +0 -29
- package/secret-contract-api.ts +0 -5
- package/setup-entry.ts +0 -13
- package/src/accounts.test.ts +0 -31
- package/src/accounts.ts +0 -149
- package/src/api-credentials.ts +0 -31
- package/src/approval-auth.test.ts +0 -17
- package/src/approval-auth.ts +0 -27
- package/src/bot-preflight.test.ts +0 -135
- package/src/bot-preflight.ts +0 -183
- package/src/channel-api.ts +0 -5
- package/src/channel.adapters.ts +0 -52
- package/src/channel.core.test.ts +0 -75
- package/src/channel.lifecycle.test.ts +0 -91
- package/src/channel.status.test.ts +0 -28
- package/src/channel.ts +0 -225
- package/src/config-schema.ts +0 -79
- package/src/core.test.ts +0 -325
- package/src/doctor-contract.ts +0 -9
- package/src/doctor.test.ts +0 -87
- package/src/doctor.ts +0 -40
- package/src/gateway.ts +0 -109
- package/src/inbound.authz.test.ts +0 -146
- package/src/inbound.behavior.test.ts +0 -309
- package/src/inbound.ts +0 -392
- package/src/message-actions.test.ts +0 -270
- package/src/message-actions.ts +0 -82
- package/src/message-adapter.ts +0 -28
- package/src/monitor-runtime.ts +0 -138
- package/src/monitor.replay.test.ts +0 -276
- package/src/monitor.test-fixtures.ts +0 -30
- package/src/monitor.test-harness.ts +0 -59
- package/src/monitor.ts +0 -385
- package/src/normalize.ts +0 -44
- package/src/policy.ts +0 -111
- package/src/replay-guard.ts +0 -128
- package/src/room-info.test.ts +0 -160
- package/src/room-info.ts +0 -130
- package/src/runtime.ts +0 -9
- package/src/secret-contract.ts +0 -103
- package/src/secret-input.ts +0 -4
- package/src/send.cfg-threading.test.ts +0 -359
- package/src/send.runtime.ts +0 -8
- package/src/send.ts +0 -269
- package/src/session-route.ts +0 -40
- package/src/setup-core.ts +0 -250
- package/src/setup-surface.ts +0 -195
- package/src/setup.test.ts +0 -445
- package/src/signature.ts +0 -82
- package/src/types.ts +0 -195
- package/tsconfig.json +0 -16
package/src/room-info.test.ts
DELETED
|
@@ -1,160 +0,0 @@
|
|
|
1
|
-
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
2
|
-
import { resolveNextcloudTalkRoomKind, testing } from "./room-info.js";
|
|
3
|
-
|
|
4
|
-
const fetchWithSsrFGuard = vi.hoisted(() => vi.fn());
|
|
5
|
-
const readFileSync = vi.hoisted(() => vi.fn());
|
|
6
|
-
|
|
7
|
-
vi.mock("../runtime-api.js", () => {
|
|
8
|
-
return vi
|
|
9
|
-
.importActual<typeof import("../runtime-api.js")>("../runtime-api.js")
|
|
10
|
-
.then((actual) => ({
|
|
11
|
-
...actual,
|
|
12
|
-
fetchWithSsrFGuard,
|
|
13
|
-
}));
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
vi.mock("node:fs", () => {
|
|
17
|
-
return vi.importActual<typeof import("node:fs")>("node:fs").then((actual) => ({
|
|
18
|
-
...actual,
|
|
19
|
-
readFileSync,
|
|
20
|
-
}));
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
afterEach(() => {
|
|
24
|
-
fetchWithSsrFGuard.mockReset();
|
|
25
|
-
readFileSync.mockReset();
|
|
26
|
-
testing.resetRoomCache();
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
function requireFirstFetchParams(): { auditContext?: string; url?: string } {
|
|
30
|
-
const [call] = fetchWithSsrFGuard.mock.calls;
|
|
31
|
-
if (!call) {
|
|
32
|
-
throw new Error("expected Nextcloud Talk room info fetch call");
|
|
33
|
-
}
|
|
34
|
-
const [fetchParams] = call;
|
|
35
|
-
if (!fetchParams || typeof fetchParams !== "object" || Array.isArray(fetchParams)) {
|
|
36
|
-
throw new Error("expected Nextcloud Talk room info fetch call");
|
|
37
|
-
}
|
|
38
|
-
return fetchParams as { auditContext?: string; url?: string };
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
describe("nextcloud talk room info", () => {
|
|
42
|
-
it("resolves direct rooms from the room info endpoint", async () => {
|
|
43
|
-
const release = vi.fn(async () => {});
|
|
44
|
-
fetchWithSsrFGuard.mockResolvedValue({
|
|
45
|
-
response: {
|
|
46
|
-
ok: true,
|
|
47
|
-
json: async () => ({
|
|
48
|
-
ocs: {
|
|
49
|
-
data: {
|
|
50
|
-
type: 1,
|
|
51
|
-
},
|
|
52
|
-
},
|
|
53
|
-
}),
|
|
54
|
-
},
|
|
55
|
-
release,
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
const kind = await resolveNextcloudTalkRoomKind({
|
|
59
|
-
account: {
|
|
60
|
-
accountId: "acct-direct",
|
|
61
|
-
baseUrl: "https://nc.example.com",
|
|
62
|
-
config: {
|
|
63
|
-
apiUser: "bot",
|
|
64
|
-
apiPassword: "secret",
|
|
65
|
-
},
|
|
66
|
-
} as never,
|
|
67
|
-
roomToken: "room-direct",
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
expect(kind).toBe("direct");
|
|
71
|
-
const fetchParams = requireFirstFetchParams();
|
|
72
|
-
expect(fetchParams.url).toBe(
|
|
73
|
-
"https://nc.example.com/ocs/v2.php/apps/spreed/api/v4/room/room-direct",
|
|
74
|
-
);
|
|
75
|
-
expect(fetchParams.auditContext).toBe("nextcloud-talk.room-info");
|
|
76
|
-
expect(release).toHaveBeenCalledTimes(1);
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
it("reads the api password from a file and logs non-ok room info responses", async () => {
|
|
80
|
-
const release = vi.fn(async () => {});
|
|
81
|
-
const log = vi.fn();
|
|
82
|
-
const error = vi.fn();
|
|
83
|
-
const exit = vi.fn();
|
|
84
|
-
readFileSync.mockReturnValue("file-secret\n");
|
|
85
|
-
fetchWithSsrFGuard.mockResolvedValue({
|
|
86
|
-
response: {
|
|
87
|
-
ok: false,
|
|
88
|
-
status: 403,
|
|
89
|
-
json: async () => ({}),
|
|
90
|
-
},
|
|
91
|
-
release,
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
const kind = await resolveNextcloudTalkRoomKind({
|
|
95
|
-
account: {
|
|
96
|
-
accountId: "acct-group",
|
|
97
|
-
baseUrl: "https://nc.example.com",
|
|
98
|
-
config: {
|
|
99
|
-
apiUser: "bot",
|
|
100
|
-
apiPasswordFile: "/tmp/nextcloud-secret",
|
|
101
|
-
},
|
|
102
|
-
} as never,
|
|
103
|
-
roomToken: "room-group",
|
|
104
|
-
runtime: { log, error, exit },
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
expect(kind).toBeUndefined();
|
|
108
|
-
expect(readFileSync).toHaveBeenCalledWith("/tmp/nextcloud-secret", "utf-8");
|
|
109
|
-
expect(log).toHaveBeenCalledWith("nextcloud-talk: room lookup failed (403) token=room-group");
|
|
110
|
-
expect(release).toHaveBeenCalledTimes(1);
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
it("reports malformed room info JSON with a stable channel error", async () => {
|
|
114
|
-
const release = vi.fn(async () => {});
|
|
115
|
-
const log = vi.fn();
|
|
116
|
-
const error = vi.fn();
|
|
117
|
-
const exit = vi.fn();
|
|
118
|
-
fetchWithSsrFGuard.mockResolvedValue({
|
|
119
|
-
response: new Response("{ nope", {
|
|
120
|
-
status: 200,
|
|
121
|
-
headers: { "content-type": "application/json" },
|
|
122
|
-
}),
|
|
123
|
-
release,
|
|
124
|
-
});
|
|
125
|
-
|
|
126
|
-
const kind = await resolveNextcloudTalkRoomKind({
|
|
127
|
-
account: {
|
|
128
|
-
accountId: "acct-malformed",
|
|
129
|
-
baseUrl: "https://nc.example.com",
|
|
130
|
-
config: {
|
|
131
|
-
apiUser: "bot",
|
|
132
|
-
apiPassword: "secret",
|
|
133
|
-
},
|
|
134
|
-
} as never,
|
|
135
|
-
roomToken: "room-malformed",
|
|
136
|
-
runtime: { log, error, exit },
|
|
137
|
-
});
|
|
138
|
-
|
|
139
|
-
expect(kind).toBeUndefined();
|
|
140
|
-
expect(error).toHaveBeenCalledWith(
|
|
141
|
-
"nextcloud-talk: room lookup error: Error: Nextcloud Talk room info failed: malformed JSON response",
|
|
142
|
-
);
|
|
143
|
-
expect(release).toHaveBeenCalledTimes(1);
|
|
144
|
-
});
|
|
145
|
-
|
|
146
|
-
it("returns undefined from room info without credentials or base url", async () => {
|
|
147
|
-
await expect(
|
|
148
|
-
resolveNextcloudTalkRoomKind({
|
|
149
|
-
account: {
|
|
150
|
-
accountId: "acct-missing",
|
|
151
|
-
baseUrl: "",
|
|
152
|
-
config: {},
|
|
153
|
-
} as never,
|
|
154
|
-
roomToken: "room-missing",
|
|
155
|
-
}),
|
|
156
|
-
).resolves.toBeUndefined();
|
|
157
|
-
|
|
158
|
-
expect(fetchWithSsrFGuard).not.toHaveBeenCalled();
|
|
159
|
-
});
|
|
160
|
-
});
|
package/src/room-info.ts
DELETED
|
@@ -1,130 +0,0 @@
|
|
|
1
|
-
import { formatErrorMessage } from "klaw/plugin-sdk/error-runtime";
|
|
2
|
-
import { readProviderJsonResponse } from "klaw/plugin-sdk/provider-http";
|
|
3
|
-
import { ssrfPolicyFromPrivateNetworkOptIn } from "klaw/plugin-sdk/ssrf-runtime";
|
|
4
|
-
import { fetchWithSsrFGuard, type RuntimeEnv } from "../runtime-api.js";
|
|
5
|
-
import type { ResolvedNextcloudTalkAccount } from "./accounts.js";
|
|
6
|
-
import { resolveNextcloudTalkApiCredentials } from "./api-credentials.js";
|
|
7
|
-
|
|
8
|
-
const ROOM_CACHE_TTL_MS = 5 * 60 * 1000;
|
|
9
|
-
const ROOM_CACHE_ERROR_TTL_MS = 30 * 1000;
|
|
10
|
-
|
|
11
|
-
const roomCache = new Map<
|
|
12
|
-
string,
|
|
13
|
-
{ kind?: "direct" | "group"; fetchedAt: number; error?: string }
|
|
14
|
-
>();
|
|
15
|
-
|
|
16
|
-
export const testing = {
|
|
17
|
-
resetRoomCache() {
|
|
18
|
-
roomCache.clear();
|
|
19
|
-
},
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
function resolveRoomCacheKey(params: { accountId: string; roomToken: string }) {
|
|
23
|
-
return `${params.accountId}:${params.roomToken}`;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
function coerceRoomType(value: unknown): number | undefined {
|
|
27
|
-
if (typeof value === "number" && Number.isFinite(value)) {
|
|
28
|
-
return value;
|
|
29
|
-
}
|
|
30
|
-
if (typeof value === "string" && value.trim()) {
|
|
31
|
-
const parsed = Number.parseInt(value, 10);
|
|
32
|
-
return Number.isFinite(parsed) ? parsed : undefined;
|
|
33
|
-
}
|
|
34
|
-
return undefined;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
function resolveRoomKindFromType(type: number | undefined): "direct" | "group" | undefined {
|
|
38
|
-
if (!type) {
|
|
39
|
-
return undefined;
|
|
40
|
-
}
|
|
41
|
-
if (type === 1 || type === 5 || type === 6) {
|
|
42
|
-
return "direct";
|
|
43
|
-
}
|
|
44
|
-
return "group";
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
export async function resolveNextcloudTalkRoomKind(params: {
|
|
48
|
-
account: ResolvedNextcloudTalkAccount;
|
|
49
|
-
roomToken: string;
|
|
50
|
-
runtime?: RuntimeEnv;
|
|
51
|
-
}): Promise<"direct" | "group" | undefined> {
|
|
52
|
-
const { account, roomToken, runtime } = params;
|
|
53
|
-
const key = resolveRoomCacheKey({ accountId: account.accountId, roomToken });
|
|
54
|
-
const cached = roomCache.get(key);
|
|
55
|
-
if (cached) {
|
|
56
|
-
const age = Date.now() - cached.fetchedAt;
|
|
57
|
-
if (cached.kind && age < ROOM_CACHE_TTL_MS) {
|
|
58
|
-
return cached.kind;
|
|
59
|
-
}
|
|
60
|
-
if (cached.error && age < ROOM_CACHE_ERROR_TTL_MS) {
|
|
61
|
-
return undefined;
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
const apiCredentials = resolveNextcloudTalkApiCredentials({
|
|
66
|
-
apiUser: account.config.apiUser,
|
|
67
|
-
apiPassword: account.config.apiPassword,
|
|
68
|
-
apiPasswordFile: account.config.apiPasswordFile,
|
|
69
|
-
});
|
|
70
|
-
if (!apiCredentials) {
|
|
71
|
-
return undefined;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
const baseUrl = account.baseUrl?.trim();
|
|
75
|
-
if (!baseUrl) {
|
|
76
|
-
return undefined;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
const url = `${baseUrl}/ocs/v2.php/apps/spreed/api/v4/room/${roomToken}`;
|
|
80
|
-
const auth = Buffer.from(
|
|
81
|
-
`${apiCredentials.apiUser}:${apiCredentials.apiPassword}`,
|
|
82
|
-
"utf-8",
|
|
83
|
-
).toString("base64");
|
|
84
|
-
|
|
85
|
-
try {
|
|
86
|
-
const { response, release } = await fetchWithSsrFGuard({
|
|
87
|
-
url,
|
|
88
|
-
init: {
|
|
89
|
-
method: "GET",
|
|
90
|
-
headers: {
|
|
91
|
-
Authorization: `Basic ${auth}`,
|
|
92
|
-
"OCS-APIRequest": "true",
|
|
93
|
-
Accept: "application/json",
|
|
94
|
-
},
|
|
95
|
-
},
|
|
96
|
-
auditContext: "nextcloud-talk.room-info",
|
|
97
|
-
policy: ssrfPolicyFromPrivateNetworkOptIn(account.config),
|
|
98
|
-
});
|
|
99
|
-
try {
|
|
100
|
-
if (!response.ok) {
|
|
101
|
-
roomCache.set(key, {
|
|
102
|
-
fetchedAt: Date.now(),
|
|
103
|
-
error: `status:${response.status}`,
|
|
104
|
-
});
|
|
105
|
-
runtime?.log?.(
|
|
106
|
-
`nextcloud-talk: room lookup failed (${response.status}) token=${roomToken}`,
|
|
107
|
-
);
|
|
108
|
-
return undefined;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
const payload = await readProviderJsonResponse<{
|
|
112
|
-
ocs?: { data?: { type?: number | string } };
|
|
113
|
-
}>(response, "Nextcloud Talk room info failed");
|
|
114
|
-
const type = coerceRoomType(payload.ocs?.data?.type);
|
|
115
|
-
const kind = resolveRoomKindFromType(type);
|
|
116
|
-
roomCache.set(key, { fetchedAt: Date.now(), kind });
|
|
117
|
-
return kind;
|
|
118
|
-
} finally {
|
|
119
|
-
await release();
|
|
120
|
-
}
|
|
121
|
-
} catch (err) {
|
|
122
|
-
roomCache.set(key, {
|
|
123
|
-
fetchedAt: Date.now(),
|
|
124
|
-
error: formatErrorMessage(err),
|
|
125
|
-
});
|
|
126
|
-
runtime?.error?.(`nextcloud-talk: room lookup error: ${String(err)}`);
|
|
127
|
-
return undefined;
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
export { testing as __testing };
|
package/src/runtime.ts
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { createPluginRuntimeStore } from "klaw/plugin-sdk/runtime-store";
|
|
2
|
-
import type { PluginRuntime } from "klaw/plugin-sdk/runtime-store";
|
|
3
|
-
|
|
4
|
-
const { setRuntime: setNextcloudTalkRuntime, getRuntime: getNextcloudTalkRuntime } =
|
|
5
|
-
createPluginRuntimeStore<PluginRuntime>({
|
|
6
|
-
pluginId: "nextcloud-talk",
|
|
7
|
-
errorMessage: "Nextcloud Talk runtime not initialized",
|
|
8
|
-
});
|
|
9
|
-
export { getNextcloudTalkRuntime, setNextcloudTalkRuntime };
|
package/src/secret-contract.ts
DELETED
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
collectConditionalChannelFieldAssignments,
|
|
3
|
-
getChannelSurface,
|
|
4
|
-
hasOwnProperty,
|
|
5
|
-
type ChannelAccountEntry,
|
|
6
|
-
type ResolverContext,
|
|
7
|
-
type SecretDefaults,
|
|
8
|
-
} from "klaw/plugin-sdk/channel-secret-basic-runtime";
|
|
9
|
-
|
|
10
|
-
export const secretTargetRegistryEntries: import("klaw/plugin-sdk/channel-secret-basic-runtime").SecretTargetRegistryEntry[] =
|
|
11
|
-
[
|
|
12
|
-
{
|
|
13
|
-
id: "channels.nextcloud-talk.accounts.*.apiPassword",
|
|
14
|
-
targetType: "channels.nextcloud-talk.accounts.*.apiPassword",
|
|
15
|
-
configFile: "klaw.json",
|
|
16
|
-
pathPattern: "channels.nextcloud-talk.accounts.*.apiPassword",
|
|
17
|
-
secretShape: "secret_input",
|
|
18
|
-
expectedResolvedValue: "string",
|
|
19
|
-
includeInPlan: true,
|
|
20
|
-
includeInConfigure: true,
|
|
21
|
-
includeInAudit: true,
|
|
22
|
-
},
|
|
23
|
-
{
|
|
24
|
-
id: "channels.nextcloud-talk.accounts.*.botSecret",
|
|
25
|
-
targetType: "channels.nextcloud-talk.accounts.*.botSecret",
|
|
26
|
-
configFile: "klaw.json",
|
|
27
|
-
pathPattern: "channels.nextcloud-talk.accounts.*.botSecret",
|
|
28
|
-
secretShape: "secret_input",
|
|
29
|
-
expectedResolvedValue: "string",
|
|
30
|
-
includeInPlan: true,
|
|
31
|
-
includeInConfigure: true,
|
|
32
|
-
includeInAudit: true,
|
|
33
|
-
},
|
|
34
|
-
{
|
|
35
|
-
id: "channels.nextcloud-talk.apiPassword",
|
|
36
|
-
targetType: "channels.nextcloud-talk.apiPassword",
|
|
37
|
-
configFile: "klaw.json",
|
|
38
|
-
pathPattern: "channels.nextcloud-talk.apiPassword",
|
|
39
|
-
secretShape: "secret_input",
|
|
40
|
-
expectedResolvedValue: "string",
|
|
41
|
-
includeInPlan: true,
|
|
42
|
-
includeInConfigure: true,
|
|
43
|
-
includeInAudit: true,
|
|
44
|
-
},
|
|
45
|
-
{
|
|
46
|
-
id: "channels.nextcloud-talk.botSecret",
|
|
47
|
-
targetType: "channels.nextcloud-talk.botSecret",
|
|
48
|
-
configFile: "klaw.json",
|
|
49
|
-
pathPattern: "channels.nextcloud-talk.botSecret",
|
|
50
|
-
secretShape: "secret_input",
|
|
51
|
-
expectedResolvedValue: "string",
|
|
52
|
-
includeInPlan: true,
|
|
53
|
-
includeInConfigure: true,
|
|
54
|
-
includeInAudit: true,
|
|
55
|
-
},
|
|
56
|
-
];
|
|
57
|
-
|
|
58
|
-
export function collectRuntimeConfigAssignments(params: {
|
|
59
|
-
config: { channels?: Record<string, unknown> };
|
|
60
|
-
defaults?: SecretDefaults;
|
|
61
|
-
context: ResolverContext;
|
|
62
|
-
}): void {
|
|
63
|
-
const resolved = getChannelSurface(params.config, "nextcloud-talk");
|
|
64
|
-
if (!resolved) {
|
|
65
|
-
return;
|
|
66
|
-
}
|
|
67
|
-
const { channel: nextcloudTalk, surface } = resolved;
|
|
68
|
-
const inheritsField =
|
|
69
|
-
(field: string) =>
|
|
70
|
-
({ account, enabled }: ChannelAccountEntry) =>
|
|
71
|
-
enabled && !hasOwnProperty(account, field);
|
|
72
|
-
collectConditionalChannelFieldAssignments({
|
|
73
|
-
channelKey: "nextcloud-talk",
|
|
74
|
-
field: "botSecret",
|
|
75
|
-
channel: nextcloudTalk,
|
|
76
|
-
surface,
|
|
77
|
-
defaults: params.defaults,
|
|
78
|
-
context: params.context,
|
|
79
|
-
topLevelActiveWithoutAccounts: true,
|
|
80
|
-
topLevelInheritedAccountActive: inheritsField("botSecret"),
|
|
81
|
-
accountActive: ({ enabled }) => enabled,
|
|
82
|
-
topInactiveReason: "no enabled Nextcloud Talk surface inherits this top-level botSecret.",
|
|
83
|
-
accountInactiveReason: "Nextcloud Talk account is disabled.",
|
|
84
|
-
});
|
|
85
|
-
collectConditionalChannelFieldAssignments({
|
|
86
|
-
channelKey: "nextcloud-talk",
|
|
87
|
-
field: "apiPassword",
|
|
88
|
-
channel: nextcloudTalk,
|
|
89
|
-
surface,
|
|
90
|
-
defaults: params.defaults,
|
|
91
|
-
context: params.context,
|
|
92
|
-
topLevelActiveWithoutAccounts: true,
|
|
93
|
-
topLevelInheritedAccountActive: inheritsField("apiPassword"),
|
|
94
|
-
accountActive: ({ enabled }) => enabled,
|
|
95
|
-
topInactiveReason: "no enabled Nextcloud Talk surface inherits this top-level apiPassword.",
|
|
96
|
-
accountInactiveReason: "Nextcloud Talk account is disabled.",
|
|
97
|
-
});
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
export const channelSecrets = {
|
|
101
|
-
secretTargetRegistryEntries,
|
|
102
|
-
collectRuntimeConfigAssignments,
|
|
103
|
-
};
|
package/src/secret-input.ts
DELETED