Skip to content

Commit

Permalink
Merge pull request matrix-org#397 from matrix-org/hs/provisioner-fixes
Browse files Browse the repository at this point in the history
Provisioner small fixes
  • Loading branch information
Half-Shot authored Apr 7, 2022
2 parents 30f6e3a + 71c1524 commit e619476
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 9 deletions.
1 change: 1 addition & 0 deletions changelog.d/397.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix an issue where the provisioner API's `/v1/exchange_openid` route would sometimes fail.
6 changes: 4 additions & 2 deletions src/provisioning/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import IPCIDR from "ip-cidr";
import { isIP } from "net";
import { promises as dns } from "dns";
import ratelimiter, { RateLimitInfo, Options as RatelimitOptions, AugmentedRequest } from "express-rate-limit";
import { Methods } from "./request";

// Borrowed from
// https://github.com/matrix-org/synapse/blob/91221b696156e9f1f9deecd425ae58af03ebb5d3/docs/sample_config.yaml#L215
Expand Down Expand Up @@ -196,7 +197,7 @@ export class ProvisioningApi {
}

public addRoute(
method: "get"|"post"|"delete"|"put",
method: Methods,
path: string,
handler: (req: ProvisioningRequest, res: Response, next?: NextFunction) => void|Promise<void>,
fnName?: string): void {
Expand Down Expand Up @@ -349,7 +350,8 @@ export class ProvisioningApi {

// Now do the token exchange
try {
const response = await axios.get<{sub: string}>(`${url}/_matrix/federation/v1/openid/userinfo`, {
const requestUrl = new URL("/_matrix/federation/v1/openid/userinfo", url);
const response = await axios.get<{sub: string}>(requestUrl.toString(), {
params: {
access_token: openIdToken,
},
Expand Down
51 changes: 45 additions & 6 deletions src/provisioning/request.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,51 @@
import Logging, { LogWrapper } from "../components/logging";
import crypto from "crypto";
import { ThinRequest } from "..";
import { Request } from "express";
import { ParsedQs } from "qs";

// Methods supported by a express.Router
export type Methods = 'all' |
'get' |
'post' |
'put' |
'delete' |
'patch' |
'options' |
'head' |
'checkout' |
'connect' |
'copy' |
'lock' |
'merge' |
'mkactivity' |
'mkcol' |
'move' |
'm-search' |
'notify' |
'propfind' |
'proppatch' |
'purge' |
'report' |
'search' |
'subscribe' |
'trace' |
'unlock' |
'unsubscribe';

export class ProvisioningRequest<
Body = Record<string, unknown>, Params = Record<string, unknown>
> implements ThinRequest {
// These types are taken from express.Request
Params = {[key: string]: string},
// eslint-disable-next-line @typescript-eslint/no-explicit-any
ResBody = any,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
ReqBody = any,
ReqQuery = ParsedQs> implements ThinRequest {
public readonly log: LogWrapper;
public readonly id: string;


constructor(
private expressReq: {body: Body, params: Params, path?: string},
public readonly expressReq: Request<Params, ResBody, ReqBody, ReqQuery>,
public readonly userId: string|null,
public readonly requestSource: "widget"|"provisioner",
public readonly widgetToken?: string,
Expand All @@ -21,18 +56,22 @@ export class ProvisioningRequest<
this.log = Logging.get(
`ProvisionRequest ${[this.id, fnName].filter(n => !!n).join(" ")}`
);
this.log.info(`New request from ${userId} via ${requestSource}`);
this.log.debug(`Request ${userId} (${requestSource}) ${this.fnName}`);
}

public getId(): string {
return this.id;
}

get body(): Body {
get body(): ReqBody {
return this.expressReq.body;
}

get params(): Params {
return this.expressReq.params;
}

get query(): ReqQuery {
return this.expressReq.query;
}
}
12 changes: 11 additions & 1 deletion src/utils/matrix-host-resolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,17 @@ export class MatrixHostResolver {
if (wellKnown.status !== 200) {
throw Error('Well known request returned non-200');
}
const mServer = wellKnown.data["m.server"];
let data: MatrixServerWellKnown;
if (typeof wellKnown.data === "object") {
data = wellKnown.data;
}
else if (typeof wellKnown.data === "string") {
data = JSON.parse(wellKnown.data);
}
else {
throw Error('Invalid datatype for well-known response');
}
const mServer = data["m.server"];
if (typeof mServer !== "string") {
throw Error("Missing 'm.server' in well-known response");
}
Expand Down

0 comments on commit e619476

Please sign in to comment.