WIP of syn2mas tool
This commit is contained in:
committed by
Quentin Gliech
parent
90aaf395d8
commit
38ed5e264e
5
.github/dependabot.yml
vendored
5
.github/dependabot.yml
vendored
@@ -68,3 +68,8 @@ updates:
|
||||
graphql-codegen:
|
||||
patterns:
|
||||
- "@graphql-codegen/*"
|
||||
|
||||
- package-ecosystem: "npm"
|
||||
directory: "/tools/syn2mas/"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
|
||||
3
.github/workflows/build.yaml
vendored
3
.github/workflows/build.yaml
vendored
@@ -5,6 +5,8 @@ on:
|
||||
branches: [ main ]
|
||||
tags:
|
||||
- 'v*'
|
||||
paths-ignore:
|
||||
- 'tools/**'
|
||||
|
||||
# Only run for pull requests if relevant files were changed
|
||||
pull_request:
|
||||
@@ -13,6 +15,7 @@ on:
|
||||
- Dockerfile
|
||||
- docker-bake.hcl
|
||||
- .github/workflows/build.yaml
|
||||
- 'tools/**'
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
|
||||
4
.github/workflows/ci.yaml
vendored
4
.github/workflows/ci.yaml
vendored
@@ -5,8 +5,12 @@ on:
|
||||
branches: [ main ]
|
||||
tags:
|
||||
- 'v*'
|
||||
paths-ignore:
|
||||
- 'tools/**'
|
||||
pull_request:
|
||||
branches: [ main ]
|
||||
paths-ignore:
|
||||
- 'tools/**'
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
|
||||
4
.github/workflows/coverage.yaml
vendored
4
.github/workflows/coverage.yaml
vendored
@@ -3,8 +3,12 @@ name: Coverage
|
||||
on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
paths-ignore:
|
||||
- 'tools/**'
|
||||
pull_request:
|
||||
branches: [ main ]
|
||||
paths-ignore:
|
||||
- 'tools/**'
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
|
||||
4
.github/workflows/docs.yaml
vendored
4
.github/workflows/docs.yaml
vendored
@@ -3,8 +3,12 @@ name: Build and deploy the documentation
|
||||
on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
paths-ignore:
|
||||
- 'tools/**'
|
||||
pull_request:
|
||||
branches: [ main ]
|
||||
paths-ignore:
|
||||
- 'tools/**'
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
|
||||
50
.github/workflows/tools.yaml
vendored
Normal file
50
.github/workflows/tools.yaml
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
name: CI for tools
|
||||
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- 'tools/**'
|
||||
pull_request:
|
||||
paths:
|
||||
- 'tools/**'
|
||||
|
||||
concurrency:
|
||||
group: tools-${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
syn2mas-lint:
|
||||
name: Check syn2mas style
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
steps:
|
||||
- name: Checkout the code
|
||||
uses: actions/checkout@v3.5.3
|
||||
|
||||
- name: Install Node
|
||||
uses: actions/setup-node@v3.7.0
|
||||
with:
|
||||
node-version-file: ./tools/syn2mas/.nvmrc
|
||||
|
||||
- name: Install Node dependencies
|
||||
working-directory: ./tools/syn2mas
|
||||
run: npm ci
|
||||
|
||||
- name: Lint
|
||||
working-directory: ./tools/syn2mas
|
||||
run: npm run lint
|
||||
|
||||
tests-done:
|
||||
name: Tests done
|
||||
if: ${{ always() }}
|
||||
needs:
|
||||
- syn2mas-lint
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: matrix-org/done-action@v2
|
||||
with:
|
||||
needs: ${{ toJSON(needs) }}
|
||||
22
tools/syn2mas/.eslintrc.cjs
Normal file
22
tools/syn2mas/.eslintrc.cjs
Normal file
@@ -0,0 +1,22 @@
|
||||
module.exports = {
|
||||
plugins: [
|
||||
'matrix-org',
|
||||
],
|
||||
extends: [
|
||||
'plugin:matrix-org/typescript',
|
||||
],
|
||||
env: {
|
||||
browser: false,
|
||||
node: true,
|
||||
},
|
||||
parser: '@typescript-eslint/parser',
|
||||
parserOptions: {
|
||||
project: "./tsconfig.json",
|
||||
},
|
||||
rules: {
|
||||
'@typescript-eslint/no-floating-promises': 'error',
|
||||
'@typescript-eslint/no-misused-promises': 'error',
|
||||
'@typescript-eslint/promise-function-async': 'error',
|
||||
'@typescript-eslint/await-thenable': 'error',
|
||||
},
|
||||
};
|
||||
2
tools/syn2mas/.gitignore
vendored
Normal file
2
tools/syn2mas/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
node_modules
|
||||
dist
|
||||
1
tools/syn2mas/.nvmrc
Normal file
1
tools/syn2mas/.nvmrc
Normal file
@@ -0,0 +1 @@
|
||||
18
|
||||
16
tools/syn2mas/README.md
Normal file
16
tools/syn2mas/README.md
Normal file
@@ -0,0 +1,16 @@
|
||||
# syn2mas - Synapse to Matrix Authentication Service
|
||||
|
||||
Tool to help with the migration of a Matrix Synapse installation to the Matrix Authentication Service.
|
||||
|
||||
The tool has two modes of operation:
|
||||
|
||||
- Advisor mode: Analyses the Synapse configuration and reports on any issues that would prevent a successful migration.
|
||||
- Migration mode: Performs the migration of the Synapse database into the Matrix Authentication Service database.
|
||||
|
||||
## Usage
|
||||
|
||||
Pre-migration advisor:
|
||||
|
||||
```sh
|
||||
npm run dev -- advisor --synapseConfigFile homeserver.yaml
|
||||
```
|
||||
6202
tools/syn2mas/package-lock.json
generated
Normal file
6202
tools/syn2mas/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
40
tools/syn2mas/package.json
Normal file
40
tools/syn2mas/package.json
Normal file
@@ -0,0 +1,40 @@
|
||||
{
|
||||
"name": "syn2mas",
|
||||
"version": "0.0.0",
|
||||
"license": "Apache-2.0",
|
||||
"author": "Matrix.org",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"build": "tsc",
|
||||
"dev": "ts-node --esm src/index.ts",
|
||||
"lint": "npm run lint:types && npm run lint:style",
|
||||
"lint:style": "eslint src",
|
||||
"lint:types": "tsc --noEmit --skipLibCheck",
|
||||
"start": "node dist/index.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/command-line-args": "^5.2.0",
|
||||
"@types/node": "^18.15.10",
|
||||
"@typescript-eslint/eslint-plugin": "^5.55.0",
|
||||
"@typescript-eslint/parser": "^5.55.0",
|
||||
"eslint": "^8.36.0",
|
||||
"eslint-config-google": "^0.14.0",
|
||||
"eslint-config-prettier": "^8.8.0",
|
||||
"eslint-plugin-import": "^2.27.5",
|
||||
"eslint-plugin-matrix-org": "github:matrix-org/eslint-plugin-matrix-org",
|
||||
"eslint-plugin-unicorn": "^46.0.0",
|
||||
"prettier": "^2.8.7",
|
||||
"ts-node": "^10.9.1",
|
||||
"typescript": "^5.0.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"command-line-args": "^5.2.1",
|
||||
"id128": "^1.6.6",
|
||||
"knex": "^2.4.2",
|
||||
"log4js": "^6.9.1",
|
||||
"pg": "^8.10.0",
|
||||
"sqlite3": "^5.1.6",
|
||||
"ts-command-line-args": "^2.4.2",
|
||||
"yaml": "^2.2.1"
|
||||
}
|
||||
}
|
||||
141
tools/syn2mas/src/advisor.mts
Normal file
141
tools/syn2mas/src/advisor.mts
Normal file
@@ -0,0 +1,141 @@
|
||||
import { readFile } from "node:fs/promises";
|
||||
import { parse } from "ts-command-line-args";
|
||||
import log4js from "log4js";
|
||||
import yaml from "yaml";
|
||||
import { Knex } from "knex";
|
||||
|
||||
import { SUser } from "./types/SUser";
|
||||
import { SynapseConfig, SynapseOIDCProvider } from "./types/SynapseConfig";
|
||||
import { connectToSynapseDatabase } from "./db.mjs";
|
||||
import { SUserThreePid } from "./types/SUserThreePid";
|
||||
import { SAccessToken } from "./types/SAccessToken";
|
||||
import { SRefreshToken } from "./types/SRefreshToken";
|
||||
|
||||
const log = log4js.getLogger("migrate");
|
||||
|
||||
interface Options {
|
||||
command: string;
|
||||
synapseConfigFile: string;
|
||||
help?: boolean;
|
||||
}
|
||||
|
||||
export async function advisor(argv?: string[]): Promise<void> {
|
||||
const args = parse<Options>({
|
||||
command: { type: String, description: "Command to run", defaultOption: true, typeLabel: "migrate" },
|
||||
synapseConfigFile: { type: String, description: "Path to synapse homeserver.yaml config file" },
|
||||
help: { type: Boolean, optional: true, alias: "h", description: "Prints this usage guide" },
|
||||
},
|
||||
{
|
||||
helpArg: "help",
|
||||
});
|
||||
|
||||
const warnings: string[] = [];
|
||||
function warn(message: string): void {
|
||||
log.warn(message);
|
||||
warnings.push(message);
|
||||
}
|
||||
|
||||
const errors: string[] = [];
|
||||
function error(message: string): void {
|
||||
log.error(message);
|
||||
errors.push(message);
|
||||
}
|
||||
|
||||
// load synapse config
|
||||
const synapseConfig: SynapseConfig = yaml.parse(await readFile(args.synapseConfigFile, "utf8"));
|
||||
|
||||
// connect to synapse databases
|
||||
const synapse = connectToSynapseDatabase(synapseConfig);
|
||||
|
||||
async function count(query: Knex.QueryBuilder): Promise<number> {
|
||||
const res = await (query.first());
|
||||
if (!res) {
|
||||
return 0;
|
||||
}
|
||||
return res["count(*)"] as number;
|
||||
}
|
||||
|
||||
const adminUsers = await count(synapse.count("*").from<SUser>("users").where({ admin: 1 }));
|
||||
if (adminUsers > 0) {
|
||||
warn(`Synapse database contains ${adminUsers} admin users which will need to be added to the MAS configuration.`);
|
||||
}
|
||||
|
||||
const guestUsers = await count(synapse.count("*").from<SUser>("users").where({ is_guest: 1 }));
|
||||
if (guestUsers > 0) {
|
||||
error(`Synapse database contains ${guestUsers} guest users which aren't supported by MAS: https://github.com/matrix-org/matrix-authentication-service/issues/1445`);
|
||||
}
|
||||
if (synapseConfig.allow_guest_access) {
|
||||
if (guestUsers > 0) {
|
||||
error("Synapse config allows guest access which isn't supported by MAS: https://github.com/matrix-org/matrix-authentication-service/issues/1445");
|
||||
} else {
|
||||
error("Synapse config allows guest access which isn't supported by MAS, but no guest users were found in the database so the option could be disabled: https://github.com/matrix-org/matrix-authentication-service/issues/1445");
|
||||
}
|
||||
}
|
||||
|
||||
if (synapseConfig.enable_registration) {
|
||||
warn("Synapse config has registration enabled which will need to be disabled after migration");
|
||||
}
|
||||
if (synapseConfig.enable_registration_captcha) {
|
||||
error("Synapse config has registration CAPTCHA enabled which isn't supported by MAS: https://github.com/matrix-org/matrix-authentication-service/issues/138");
|
||||
}
|
||||
|
||||
const usersWithoutEmailAddress = await count(synapse.count("*").from<SUser>("users").leftOuterJoin<SUserThreePid>("user_threepids", "users.name", "user_threepids.user_id").whereNull("user_threepids.user_id"));
|
||||
if (usersWithoutEmailAddress > 0) {
|
||||
warn(`Synapse database contains ${usersWithoutEmailAddress} users without a verified email address who will need to verify their email address before they can login after migration: https://github.com/matrix-org/matrix-authentication-service/issues/1505`);
|
||||
}
|
||||
|
||||
const deactivatedUsers = await count(synapse.count("*").from<SUser>("users").where({ deactivated: 1 }));
|
||||
if (deactivatedUsers > 0) {
|
||||
error(`Synapse database contains ${deactivatedUsers} deactivated users which aren't supported during migration`);
|
||||
}
|
||||
|
||||
const accessTokensWithoutDeviceId = await count(synapse.count("*").from<SAccessToken>("access_tokens").where({ device_id: "" }).orWhereNull("device_id"));
|
||||
if (accessTokensWithoutDeviceId > 0) {
|
||||
error(`Synapse database contains ${accessTokensWithoutDeviceId} access tokens without an associated device_id which aren't supported during migration`);
|
||||
}
|
||||
|
||||
const nonEmailThreePids = await count(synapse.count("*").from<SUserThreePid>("user_threepids").whereNot({ medium: "email" }));
|
||||
if (nonEmailThreePids > 0) {
|
||||
error(`Synapse database contains ${nonEmailThreePids} non-email 3pids which will be ignored during migration`);
|
||||
}
|
||||
|
||||
const oidcProviders: SynapseOIDCProvider[] = [...(synapseConfig.oidc_providers ?? []), ...(synapseConfig.oidc_config ? [synapseConfig.oidc_config] : [])];
|
||||
for (const provider of oidcProviders) {
|
||||
warn(`Synapse config contains OIDC auth configuration which will need mapping to be manually mapped to an upstream OpenID Provider during migration: ${provider.issuer}`);
|
||||
}
|
||||
|
||||
if (synapseConfig.cas_config?.enabled) {
|
||||
warn("Synapse config contains CAS auth configuration which will need mapping to be manually mapped to an upstream OpenID Provider during migration");
|
||||
}
|
||||
if (synapseConfig.saml2_config?.sp_config) {
|
||||
warn("Synapse config contains SAML2 auth configuration which will need mapping to be manually mapped to an upstream OpenID Provider during migration");
|
||||
}
|
||||
if (synapseConfig.jwt_config?.enabled) {
|
||||
warn("Synapse config contains JWT auth configuration which will need mapping to be manually mapped to an upstream OpenID Provider during migration");
|
||||
}
|
||||
if (synapseConfig.password_config?.enabled !== false && synapseConfig.password_config?.localdb_enabled === false) {
|
||||
warn("Synapse has a non-standard password auth enabled which won't work after migration and will need to be manually mapped to an upstream OpenID Provider during migration");
|
||||
} else if (synapseConfig.password_config?.enabled !== false) {
|
||||
warn("Migration of Synapse password auth is not yet supported");
|
||||
}
|
||||
|
||||
const externalIdAuthProviders = await synapse.select("auth_provider").count("* as Count").from("user_external_ids").groupBy("auth_provider") as { auth_provider: string; "Count": number }[];
|
||||
for (const row of externalIdAuthProviders) {
|
||||
warn(`An upstream OpenID Provider will need to be configured for the ${row.Count} users with auth provider ${row.auth_provider}`);
|
||||
}
|
||||
|
||||
const usersWithPassword = await count(synapse.count("*").from<SUser>("users").whereNotNull("password_hash"));
|
||||
if (usersWithPassword > 0) {
|
||||
warn(`Synapse database contains ${usersWithPassword} users with a password which will be migrated. However, support for password auth in MAS is not feature complete`);
|
||||
}
|
||||
|
||||
const accessTokensToImport = await count(synapse.count("*").from<SAccessToken>("access_tokens").whereNotNull("device_id"));
|
||||
if (accessTokensToImport > 0) {
|
||||
log.info(`Synapse database contains ${accessTokensToImport} access tokens which will be migrated`);
|
||||
}
|
||||
|
||||
const synapseRefreshToken = await count(synapse.select("*").from<SRefreshToken>("refresh_tokens"));
|
||||
if (synapseRefreshToken > 0) {
|
||||
log.info(`Synapse database contains ${synapseRefreshToken} refresh tokens which will be migrated`);
|
||||
}
|
||||
}
|
||||
26
tools/syn2mas/src/db.mts
Normal file
26
tools/syn2mas/src/db.mts
Normal file
@@ -0,0 +1,26 @@
|
||||
import knex, { Knex } from "knex";
|
||||
|
||||
import { SynapseConfig } from "./types/SynapseConfig";
|
||||
import { MASConfig } from "./types/MASConfig";
|
||||
|
||||
export function connectToSynapseDatabase({ database }: SynapseConfig): Knex<{}, unknown[]> {
|
||||
if (database?.name === "sqlite3") {
|
||||
return knex({ client: "sqlite3", connection: { filename: database.args.database }, useNullAsDefault: true });
|
||||
}
|
||||
|
||||
if (database.name === "psycopg2") {
|
||||
return knex({ client: "pg", connection: {
|
||||
user: database?.args?.user,
|
||||
database: database?.args?.database,
|
||||
password: database?.args?.password,
|
||||
port: database?.args?.port,
|
||||
host: database?.args?.host,
|
||||
} });
|
||||
}
|
||||
|
||||
throw new Error(`Unsupported database type ${database?.name}. Must be sqlite3 or psycopg2`);
|
||||
}
|
||||
|
||||
export function connectToMASDatabase({ database }: MASConfig): Knex<{}, unknown[]> {
|
||||
return knex({ client: "pg", connection: database?.uri });
|
||||
}
|
||||
46
tools/syn2mas/src/index.ts
Normal file
46
tools/syn2mas/src/index.ts
Normal file
@@ -0,0 +1,46 @@
|
||||
import { ArgumentConfig, parse } from "ts-command-line-args";
|
||||
import log4js from "log4js";
|
||||
|
||||
// import { migrate } from "./migrate.mjs";
|
||||
import { advisor } from "./advisor.mjs";
|
||||
|
||||
log4js.configure({
|
||||
appenders: {
|
||||
console: { type: "console" },
|
||||
},
|
||||
categories: {
|
||||
default: { appenders: ["console"], level: "debug" },
|
||||
},
|
||||
});
|
||||
|
||||
const log = log4js.getLogger();
|
||||
|
||||
interface MainOptions {
|
||||
command: string;
|
||||
help?: boolean;
|
||||
}
|
||||
|
||||
const mainArgOptions: ArgumentConfig<MainOptions> = {
|
||||
command: { type: String, description: "Command to run", defaultOption: true, typeLabel: "<advisor|migrate>" },
|
||||
help: { type: Boolean, optional: true, alias: "h", description: "Prints this usage guide" },
|
||||
};
|
||||
|
||||
export const mainArgs = parse<MainOptions>(mainArgOptions, { stopAtFirstUnknown: true });
|
||||
|
||||
try {
|
||||
// if (mainArgs.command === "migrate") {
|
||||
// await migrate();
|
||||
// process.exit(0);
|
||||
// }
|
||||
|
||||
if (mainArgs.command === "advisor") {
|
||||
await advisor();
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
parse<MainOptions>(mainArgOptions, { helpArg: "help" });
|
||||
process.exit(1);
|
||||
} catch (e) {
|
||||
log.error(e);
|
||||
process.exit(1);
|
||||
}
|
||||
8
tools/syn2mas/src/types/MASConfig.d.ts
vendored
Normal file
8
tools/syn2mas/src/types/MASConfig.d.ts
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
export interface MASConfig {
|
||||
database?: {
|
||||
uri?: string;
|
||||
};
|
||||
secrets?: {
|
||||
encryption?: string;
|
||||
};
|
||||
}
|
||||
29
tools/syn2mas/src/types/MCompatAccessToken.d.ts
vendored
Normal file
29
tools/syn2mas/src/types/MCompatAccessToken.d.ts
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
import { UUID } from "./index";
|
||||
import { MCompatSession } from "./MCompatSession";
|
||||
|
||||
/*
|
||||
+------------------------+--------------------------+-----------+
|
||||
| Column | Type | Modifiers |
|
||||
|------------------------+--------------------------+-----------|
|
||||
| compat_access_token_id | uuid | not null |
|
||||
| compat_session_id | uuid | not null |
|
||||
| access_token | text | not null |
|
||||
| created_at | timestamp with time zone | not null |
|
||||
| expires_at | timestamp with time zone | |
|
||||
+------------------------+--------------------------+-----------+
|
||||
Indexes:
|
||||
"compat_access_tokens_pkey" PRIMARY KEY, btree (compat_access_token_id)
|
||||
"compat_access_tokens_access_token_unique" UNIQUE CONSTRAINT, btree (access_token)
|
||||
Foreign-key constraints:
|
||||
"compat_access_tokens_compat_session_id_fkey" FOREIGN KEY (compat_session_id) REFERENCES compat_sessions(compat_session_id)
|
||||
Referenced by:
|
||||
TABLE "compat_refresh_tokens" CONSTRAINT "compat_refresh_tokens_compat_access_token_id_fkey" FOREIGN KEY (compat_access_token_id) REFERENCES compat_access_tokens(compat_access_toke
|
||||
n_id)
|
||||
*/
|
||||
export interface MCompatAccessToken {
|
||||
compat_access_token_id: UUID<MCompatAccessToken>;
|
||||
compat_session_id: UUID<MCompatSession>;
|
||||
access_token: string;
|
||||
created_at: Date;
|
||||
expires_at?: Date;
|
||||
}
|
||||
30
tools/syn2mas/src/types/MCompatRefreshToken.d.ts
vendored
Normal file
30
tools/syn2mas/src/types/MCompatRefreshToken.d.ts
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
import { MCompatAccessToken } from "./MCompatAccessToken";
|
||||
import { UUID } from "./index";
|
||||
import { MCompatSession } from "./MCompatSession";
|
||||
|
||||
/*
|
||||
+-------------------------+--------------------------+-----------+
|
||||
| Column | Type | Modifiers |
|
||||
|-------------------------+--------------------------+-----------|
|
||||
| compat_refresh_token_id | uuid | not null |
|
||||
| compat_session_id | uuid | not null |
|
||||
| compat_access_token_id | uuid | not null |
|
||||
| refresh_token | text | not null |
|
||||
| created_at | timestamp with time zone | not null |
|
||||
| consumed_at | timestamp with time zone | |
|
||||
+-------------------------+--------------------------+-----------+
|
||||
Indexes:
|
||||
"compat_refresh_tokens_pkey" PRIMARY KEY, btree (compat_refresh_token_id)
|
||||
"compat_refresh_tokens_refresh_token_unique" UNIQUE CONSTRAINT, btree (refresh_token)
|
||||
Foreign-key constraints:
|
||||
"compat_refresh_tokens_compat_access_token_id_fkey" FOREIGN KEY (compat_access_token_id) REFERENCES compat_access_tokens(compat_access_token_id)
|
||||
"compat_refresh_tokens_compat_session_id_fkey" FOREIGN KEY (compat_session_id) REFERENCES compat_sessions(compat_session_id)
|
||||
*/
|
||||
export interface MCompatRefreshToken {
|
||||
compat_refresh_token_id: UUID<MCompatRefreshToken>;
|
||||
compat_session_id: UUID<MCompatSession>;
|
||||
compat_access_token_id: UUID<MCompatAccessToken>;
|
||||
refresh_token: string;
|
||||
created_at: Date;
|
||||
consumed_at?: Date;
|
||||
}
|
||||
33
tools/syn2mas/src/types/MCompatSession.d.ts
vendored
Normal file
33
tools/syn2mas/src/types/MCompatSession.d.ts
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
import { MUser } from "./MUser";
|
||||
import { UUID } from "./index";
|
||||
|
||||
/*
|
||||
+-------------------+--------------------------+-----------+
|
||||
| Column | Type | Modifiers |
|
||||
|-------------------+--------------------------+-----------|
|
||||
| compat_session_id | uuid | not null |
|
||||
| user_id | uuid | not null |
|
||||
| device_id | text | not null |
|
||||
| created_at | timestamp with time zone | not null |
|
||||
| finished_at | timestamp with time zone | |
|
||||
| is_synapse_admin | boolean | not null |
|
||||
+-------------------+--------------------------+-----------+
|
||||
Indexes:
|
||||
"compat_sessions_pkey" PRIMARY KEY, btree (compat_session_id)
|
||||
"compat_sessions_device_id_unique" UNIQUE CONSTRAINT, btree (device_id)
|
||||
Foreign-key constraints:
|
||||
"compat_sessions_user_id_fkey" FOREIGN KEY (user_id) REFERENCES users(user_id)
|
||||
Referenced by:
|
||||
TABLE "compat_sso_logins" CONSTRAINT "compat_sso_logins_compat_session_id_fkey" FOREIGN KEY (compat_session_id) REFERENCES compat_sessions(compat_session_id) ON DELETE SET NULL
|
||||
TABLE "compat_access_tokens" CONSTRAINT "compat_access_tokens_compat_session_id_fkey" FOREIGN KEY (compat_session_id) REFERENCES compat_sessions(compat_session_id)
|
||||
TABLE "compat_refresh_tokens" CONSTRAINT "compat_refresh_tokens_compat_session_id_fkey" FOREIGN KEY (compat_session_id) REFERENCES compat_sessions(compat_session_id)
|
||||
*/
|
||||
|
||||
export interface MCompatSession {
|
||||
compat_session_id: UUID<MCompatSession>;
|
||||
user_id: UUID<MUser>;
|
||||
device_id: string;
|
||||
created_at: Date;
|
||||
finished_at?: Date;
|
||||
is_synapse_admin: boolean;
|
||||
}
|
||||
30
tools/syn2mas/src/types/MUpstreamOauthLink.d.ts
vendored
Normal file
30
tools/syn2mas/src/types/MUpstreamOauthLink.d.ts
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
import { MUser } from "./MUser";
|
||||
import { UUID } from "./index";
|
||||
import { MUpstreamOauthProvider } from "./MUpstreamOauthProvider";
|
||||
|
||||
/*
|
||||
+----------------------------+--------------------------+-----------+
|
||||
| Column | Type | Modifiers |
|
||||
|----------------------------+--------------------------+-----------|
|
||||
| upstream_oauth_link_id | uuid | not null |
|
||||
| upstream_oauth_provider_id | uuid | not null |
|
||||
| user_id | uuid | |
|
||||
| subject | text | not null |
|
||||
| created_at | timestamp with time zone | not null |
|
||||
+----------------------------+--------------------------+-----------+
|
||||
Indexes:
|
||||
"upstream_oauth_links_pkey" PRIMARY KEY, btree (upstream_oauth_link_id)
|
||||
"upstream_oauth_links_subject_unique" UNIQUE CONSTRAINT, btree (upstream_oauth_provider_id, subject)
|
||||
Foreign-key constraints:
|
||||
"upstream_oauth_link_user_fkey" FOREIGN KEY (user_id) REFERENCES users(user_id)
|
||||
"upstream_oauth_links_provider_fkey" FOREIGN KEY (upstream_oauth_provider_id) REFERENCES upstream_oauth_providers(upstream_oauth_provider_id)
|
||||
Referenced by:
|
||||
TABLE "upstream_oauth_authorization_sessions" CONSTRAINT "upstream_oauth_authorization_sessions_link_fkey" FOREIGN KEY (upstream_oauth_link_id) REFERENCES upstream_oauth_links(upstream_oauth_link_id)
|
||||
*/
|
||||
export interface MUpstreamOauthLink {
|
||||
upstream_oauth_link_id: UUID<MUpstreamOauthLink>;
|
||||
upstream_oauth_provider_id: UUID<MUpstreamOauthProvider>;
|
||||
user_id?: UUID<MUser>;
|
||||
subject: string;
|
||||
created_at: Date;
|
||||
}
|
||||
32
tools/syn2mas/src/types/MUpstreamOauthProvider.d.ts
vendored
Normal file
32
tools/syn2mas/src/types/MUpstreamOauthProvider.d.ts
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
import { UUID } from "./index";
|
||||
|
||||
/*
|
||||
+----------------------------+--------------------------+-----------+
|
||||
| Column | Type | Modifiers |
|
||||
|----------------------------+--------------------------+-----------|
|
||||
| upstream_oauth_provider_id | uuid | not null |
|
||||
| issuer | text | not null |
|
||||
| scope | text | not null |
|
||||
| client_id | text | not null |
|
||||
| encrypted_client_secret | text | |
|
||||
| token_endpoint_signing_alg | text | |
|
||||
| token_endpoint_auth_method | text | not null |
|
||||
| created_at | timestamp with time zone | not null |
|
||||
+----------------------------+--------------------------+-----------+
|
||||
Indexes:
|
||||
"upstream_oauth_providers_pkey" PRIMARY KEY, btree (upstream_oauth_provider_id)
|
||||
Referenced by:
|
||||
TABLE "upstream_oauth_links" CONSTRAINT "upstream_oauth_links_provider_fkey" FOREIGN KEY (upstream_oauth_provider_id) REFERENCES upstream_oauth_providers(upstream_oauth_provider_id)
|
||||
TABLE "upstream_oauth_authorization_sessions" CONSTRAINT "upstream_oauth_authorization_sessions_provider_fkey" FOREIGN KEY (upstream_oauth_provider_id) REFERENCES upstream_oauth_providers(upstream_oauth_provider_id)
|
||||
*/
|
||||
|
||||
export interface MUpstreamOauthProvider {
|
||||
upstream_oauth_provider_id: UUID<MUpstreamOauthProvider>;
|
||||
issuer: string;
|
||||
scope: string;
|
||||
client_id: string;
|
||||
encrypted_client_secret?: string;
|
||||
token_endpoint_signing_alg?: string;
|
||||
token_endpoint_auth_method: string;
|
||||
created_at: Date;
|
||||
}
|
||||
9
tools/syn2mas/src/types/MUser.d.ts
vendored
Normal file
9
tools/syn2mas/src/types/MUser.d.ts
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
import { UUID } from "./index";
|
||||
import { MUserEmail } from "./MUserEmail";
|
||||
|
||||
export interface MUser {
|
||||
user_id: UUID<MUser>;
|
||||
username: string; // localpart only without @
|
||||
created_at: Date;
|
||||
primary_user_email_id?: UUID<MUserEmail>;
|
||||
}
|
||||
22
tools/syn2mas/src/types/MUserEmail.d.ts
vendored
Normal file
22
tools/syn2mas/src/types/MUserEmail.d.ts
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
import { MUser } from "./MUser";
|
||||
import { UUID } from "./index";
|
||||
|
||||
/*
|
||||
+---------------+--------------------------+-----------+
|
||||
| Column | Type | Modifiers |
|
||||
|---------------+--------------------------+-----------|
|
||||
| user_email_id | uuid | not null |
|
||||
| user_id | uuid | not null |
|
||||
| email | text | not null |
|
||||
| created_at | timestamp with time zone | not null |
|
||||
| confirmed_at | timestamp with time zone | |
|
||||
+---------------+--------------------------+-----------+
|
||||
*/
|
||||
|
||||
export interface MUserEmail {
|
||||
user_email_id: UUID<MUserEmail>;
|
||||
user_id: UUID<MUser>;
|
||||
email: string;
|
||||
created_at: Date;
|
||||
confirmed_at?: Date;
|
||||
}
|
||||
11
tools/syn2mas/src/types/MUserPassword.d.ts
vendored
Normal file
11
tools/syn2mas/src/types/MUserPassword.d.ts
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
import { MUser } from "./MUser";
|
||||
import { UUID } from "./index";
|
||||
|
||||
export interface MUserPassword {
|
||||
user_password_id: UUID<MUserPassword>;
|
||||
user_id: UUID<MUser>;
|
||||
hashed_password: string;
|
||||
created_at: Date;
|
||||
version: number;
|
||||
upgraded_from_id?: UUID<MUserPassword>;
|
||||
}
|
||||
27
tools/syn2mas/src/types/SAccessToken.d.ts
vendored
Normal file
27
tools/syn2mas/src/types/SAccessToken.d.ts
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
import { Id, SynapseUserId } from "./index";
|
||||
import { SRefreshToken } from "./SRefreshToken";
|
||||
|
||||
/*
|
||||
CREATE TABLE access_tokens (
|
||||
id bigint NOT NULL,
|
||||
user_id text NOT NULL,
|
||||
device_id text,
|
||||
token text NOT NULL,
|
||||
valid_until_ms bigint,
|
||||
puppets_user_id text,
|
||||
last_validated bigint,
|
||||
refresh_token_id bigint,
|
||||
used boolean
|
||||
);
|
||||
*/
|
||||
export interface SAccessToken {
|
||||
id: Id<SAccessToken>;
|
||||
user_id: SynapseUserId;
|
||||
device_id?: string;
|
||||
token: string;
|
||||
valid_until_ms?: number;
|
||||
puppets_user_id?: SynapseUserId;
|
||||
last_validated?: number;
|
||||
refresh_token_id?: Id<SRefreshToken>;
|
||||
used: boolean;
|
||||
}
|
||||
24
tools/syn2mas/src/types/SRefreshToken.d.ts
vendored
Normal file
24
tools/syn2mas/src/types/SRefreshToken.d.ts
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
import { Id, SynapseUserId } from "./index";
|
||||
|
||||
/*
|
||||
);
|
||||
CREATE TABLE refresh_tokens (
|
||||
id bigint NOT NULL,
|
||||
user_id text NOT NULL,
|
||||
device_id text NOT NULL,
|
||||
token text NOT NULL,
|
||||
next_token_id bigint,
|
||||
expiry_ts bigint,
|
||||
ultimate_session_expiry_ts bigint
|
||||
);
|
||||
*/
|
||||
|
||||
export interface SRefreshToken {
|
||||
id: Id<SRefreshToken>;
|
||||
user_id: SynapseUserId;
|
||||
device_id: string;
|
||||
token: string;
|
||||
next_token_id?: number; // refresh or access?
|
||||
expiry_ts?: number;
|
||||
ultimate_session_expiry_ts?: number;
|
||||
}
|
||||
10
tools/syn2mas/src/types/SUser.d.ts
vendored
Normal file
10
tools/syn2mas/src/types/SUser.d.ts
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
import { SynapseUserId, UnixTimestamp } from "./index";
|
||||
|
||||
export interface SUser {
|
||||
name: SynapseUserId; // '@test2:localhost:8008'
|
||||
password_hash?: string;
|
||||
admin: number;
|
||||
is_guest: number;
|
||||
deactivated: number;
|
||||
creation_ts: UnixTimestamp;
|
||||
}
|
||||
7
tools/syn2mas/src/types/SUserExternalId.d.ts
vendored
Normal file
7
tools/syn2mas/src/types/SUserExternalId.d.ts
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
import { SynapseUserId } from "./index";
|
||||
|
||||
export interface SUserExternalId {
|
||||
auth_provider: string;
|
||||
external_id: string;
|
||||
user_id: SynapseUserId;
|
||||
}
|
||||
18
tools/syn2mas/src/types/SUserThreePid.d.ts
vendored
Normal file
18
tools/syn2mas/src/types/SUserThreePid.d.ts
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
import { SynapseUserId } from "./index";
|
||||
|
||||
/*
|
||||
CREATE TABLE user_threepids (
|
||||
user_id text NOT NULL,
|
||||
medium text NOT NULL,
|
||||
address text NOT NULL,
|
||||
validated_at bigint NOT NULL,
|
||||
added_at bigint NOT NULL
|
||||
);
|
||||
*/
|
||||
export interface SUserThreePid {
|
||||
user_id: SynapseUserId;
|
||||
medium: string;
|
||||
address: string;
|
||||
validated_at: number;
|
||||
added_at: number;
|
||||
}
|
||||
51
tools/syn2mas/src/types/SynapseConfig.d.ts
vendored
Normal file
51
tools/syn2mas/src/types/SynapseConfig.d.ts
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
export interface SynapseOIDCProvider {
|
||||
idp_id: string;
|
||||
idp_name: string;
|
||||
issuer: string;
|
||||
client_id: string;
|
||||
scopes: string[];
|
||||
client_auth_method?: "client_secret_basic" | "client_secret_post" | "none";
|
||||
client_secret?: string;
|
||||
client_secret_jwt_key?: string;
|
||||
}
|
||||
|
||||
export interface SynapseConfig {
|
||||
database?: {
|
||||
name: "sqlite3";
|
||||
args?: {
|
||||
database: string;
|
||||
};
|
||||
} | {
|
||||
name: "psycopg2";
|
||||
args?: {
|
||||
user?: string;
|
||||
password?: string;
|
||||
database?: string;
|
||||
host?: string;
|
||||
port?: number;
|
||||
};
|
||||
} | any;
|
||||
|
||||
oidc_providers?: SynapseOIDCProvider[];
|
||||
oidc_config?: SynapseOIDCProvider;
|
||||
allow_guest_access?: boolean;
|
||||
cas_config?: {
|
||||
enabled?: boolean;
|
||||
};
|
||||
saml2_config?: {
|
||||
sp_config?: {};
|
||||
};
|
||||
sso?: {
|
||||
client_whitelist?: string[];
|
||||
update_profile_information?: boolean;
|
||||
};
|
||||
jwt_config?: {
|
||||
enabled?: boolean;
|
||||
};
|
||||
password_config?: {
|
||||
enabled?: boolean;
|
||||
localdb_enabled?: boolean;
|
||||
};
|
||||
enable_registration_captcha?: boolean;
|
||||
enable_registration?: boolean;
|
||||
}
|
||||
6
tools/syn2mas/src/types/index.d.ts
vendored
Normal file
6
tools/syn2mas/src/types/index.d.ts
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
export type UnixTimestamp = number;
|
||||
export type SynapseUserId = string;
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
export type Id<T> = number;
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
export type UUID<T> = string;
|
||||
7
tools/syn2mas/src/types/knex.d.ts
vendored
Normal file
7
tools/syn2mas/src/types/knex.d.ts
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
import "knex/types/result";
|
||||
|
||||
declare module "knex/types/result" {
|
||||
interface Registry {
|
||||
Count: number;
|
||||
}
|
||||
}
|
||||
16
tools/syn2mas/tsconfig.json
Normal file
16
tools/syn2mas/tsconfig.json
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2022",
|
||||
"module": "ES2022",
|
||||
"lib": ["ES2022"],
|
||||
"moduleResolution": "node",
|
||||
"strict": true,
|
||||
"sourceMap": true,
|
||||
"declaration": false,
|
||||
"outDir": "./dist",
|
||||
"rootDir": "./src",
|
||||
"esModuleInterop": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"skipLibCheck": true
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user