You've already forked matrix-js-sdk
mirror of
https://github.com/matrix-org/matrix-js-sdk.git
synced 2025-08-09 10:22:46 +03:00
Use server name instead of homeserver url to allow well-known lookups during QR OIDC reciprocation (#4233)
* Use server name instead of homeserver url to allow well-known lookups during QR OIDC reciprocation Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Iterate Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Iterate Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Iterate Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Iterate Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --------- Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
This commit is contained in:
committed by
GitHub
parent
987ec1e62f
commit
c55289ec65
@@ -53,7 +53,7 @@
|
|||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": "^7.12.5",
|
"@babel/runtime": "^7.12.5",
|
||||||
"@matrix-org/matrix-sdk-crypto-wasm": "^5.0.0",
|
"@matrix-org/matrix-sdk-crypto-wasm": "^6.0.0",
|
||||||
"another-json": "^0.2.0",
|
"another-json": "^0.2.0",
|
||||||
"bs58": "^5.0.0",
|
"bs58": "^5.0.0",
|
||||||
"content-type": "^1.0.4",
|
"content-type": "^1.0.4",
|
||||||
|
@@ -54,9 +54,7 @@ function makeMockClient(opts: { userId: string; deviceId: string; msc4108Enabled
|
|||||||
return opts.deviceId;
|
return opts.deviceId;
|
||||||
},
|
},
|
||||||
baseUrl,
|
baseUrl,
|
||||||
getHomeserverUrl() {
|
getDomain: () => "example.com",
|
||||||
return baseUrl;
|
|
||||||
},
|
|
||||||
getDevice: jest.fn(),
|
getDevice: jest.fn(),
|
||||||
getCrypto: jest.fn(() => crypto),
|
getCrypto: jest.fn(() => crypto),
|
||||||
getAuthIssuer: jest.fn().mockResolvedValue({ issuer: "https://issuer/" }),
|
getAuthIssuer: jest.fn().mockResolvedValue({ issuer: "https://issuer/" }),
|
||||||
@@ -157,19 +155,19 @@ describe("MSC4108SignInWithQR", () => {
|
|||||||
client = makeMockClient({ userId: "@alice:example.com", deviceId: "alice", msc4108Enabled: true });
|
client = makeMockClient({ userId: "@alice:example.com", deviceId: "alice", msc4108Enabled: true });
|
||||||
|
|
||||||
const ourChannel = new MSC4108SecureChannel(ourMockSession);
|
const ourChannel = new MSC4108SecureChannel(ourMockSession);
|
||||||
const qrCodeData = QrCodeData.from_bytes(
|
const qrCodeData = QrCodeData.fromBytes(
|
||||||
await ourChannel.generateCode(QrCodeMode.Reciprocate, client.getHomeserverUrl()),
|
await ourChannel.generateCode(QrCodeMode.Reciprocate, client.getDomain()!),
|
||||||
);
|
);
|
||||||
const opponentChannel = new MSC4108SecureChannel(opponentMockSession, qrCodeData.public_key);
|
const opponentChannel = new MSC4108SecureChannel(opponentMockSession, qrCodeData.publicKey);
|
||||||
|
|
||||||
ourLogin = new MSC4108SignInWithQR(ourChannel, true, client);
|
ourLogin = new MSC4108SignInWithQR(ourChannel, true, client);
|
||||||
opponentLogin = new MSC4108SignInWithQR(opponentChannel, false);
|
opponentLogin = new MSC4108SignInWithQR(opponentChannel, false);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should be able to connect with opponent and share homeserver url & check code", async () => {
|
it("should be able to connect with opponent and share server name & check code", async () => {
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
expect(ourLogin.negotiateProtocols()).resolves.toEqual({}),
|
expect(ourLogin.negotiateProtocols()).resolves.toEqual({}),
|
||||||
expect(opponentLogin.negotiateProtocols()).resolves.toEqual({ homeserverBaseUrl: client.baseUrl }),
|
expect(opponentLogin.negotiateProtocols()).resolves.toEqual({ serverName: client.getDomain() }),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
expect(ourLogin.checkCode).toBe(opponentLogin.checkCode);
|
expect(ourLogin.checkCode).toBe(opponentLogin.checkCode);
|
||||||
|
@@ -44,9 +44,9 @@ describe("MSC4108SecureChannel", () => {
|
|||||||
} as unknown as MSC4108RendezvousSession;
|
} as unknown as MSC4108RendezvousSession;
|
||||||
const channel = new MSC4108SecureChannel(mockSession);
|
const channel = new MSC4108SecureChannel(mockSession);
|
||||||
|
|
||||||
const qrCodeData = QrCodeData.from_bytes(await channel.generateCode(QrCodeMode.Reciprocate, baseUrl));
|
const qrCodeData = QrCodeData.fromBytes(await channel.generateCode(QrCodeMode.Reciprocate, baseUrl));
|
||||||
const { initial_message: ciphertext } = new Ecies().establish_outbound_channel(
|
const { initial_message: ciphertext } = new Ecies().establish_outbound_channel(
|
||||||
qrCodeData.public_key,
|
qrCodeData.publicKey,
|
||||||
"MATRIX_QR_CODE_LOGIN_INITIATE",
|
"MATRIX_QR_CODE_LOGIN_INITIATE",
|
||||||
);
|
);
|
||||||
mocked(mockSession.receive).mockResolvedValue(ciphertext);
|
mocked(mockSession.receive).mockResolvedValue(ciphertext);
|
||||||
@@ -65,9 +65,9 @@ describe("MSC4108SecureChannel", () => {
|
|||||||
mocked(mockSession.receive).mockResolvedValue("");
|
mocked(mockSession.receive).mockResolvedValue("");
|
||||||
await expect(channel.connect()).rejects.toThrow("No response from other device");
|
await expect(channel.connect()).rejects.toThrow("No response from other device");
|
||||||
|
|
||||||
const qrCodeData = QrCodeData.from_bytes(await channel.generateCode(QrCodeMode.Reciprocate, baseUrl));
|
const qrCodeData = QrCodeData.fromBytes(await channel.generateCode(QrCodeMode.Reciprocate, baseUrl));
|
||||||
const { initial_message: ciphertext } = new Ecies().establish_outbound_channel(
|
const { initial_message: ciphertext } = new Ecies().establish_outbound_channel(
|
||||||
qrCodeData.public_key,
|
qrCodeData.publicKey,
|
||||||
"NOT_REAL_MATRIX_QR_CODE_LOGIN_INITIATE",
|
"NOT_REAL_MATRIX_QR_CODE_LOGIN_INITIATE",
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -88,9 +88,9 @@ describe("MSC4108SecureChannel", () => {
|
|||||||
} as unknown as MSC4108RendezvousSession;
|
} as unknown as MSC4108RendezvousSession;
|
||||||
channel = new MSC4108SecureChannel(mockSession);
|
channel = new MSC4108SecureChannel(mockSession);
|
||||||
|
|
||||||
const qrCodeData = QrCodeData.from_bytes(await channel.generateCode(QrCodeMode.Reciprocate, baseUrl));
|
const qrCodeData = QrCodeData.fromBytes(await channel.generateCode(QrCodeMode.Reciprocate, baseUrl));
|
||||||
const { channel: _opponentChannel, initial_message: ciphertext } = new Ecies().establish_outbound_channel(
|
const { channel: _opponentChannel, initial_message: ciphertext } = new Ecies().establish_outbound_channel(
|
||||||
qrCodeData.public_key,
|
qrCodeData.publicKey,
|
||||||
"MATRIX_QR_CODE_LOGIN_INITIATE",
|
"MATRIX_QR_CODE_LOGIN_INITIATE",
|
||||||
);
|
);
|
||||||
opponentChannel = _opponentChannel;
|
opponentChannel = _opponentChannel;
|
||||||
|
4
src/@types/matrix-sdk-crypto-wasm.d.ts
vendored
4
src/@types/matrix-sdk-crypto-wasm.d.ts
vendored
@@ -37,4 +37,8 @@ declare module "@matrix-org/matrix-sdk-crypto-wasm" {
|
|||||||
};
|
};
|
||||||
}>;
|
}>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface Device {
|
||||||
|
requestVerification(methods?: any[]): [RustSdkCryptoJs.VerificationRequest, RustSdkCryptoJs.ToDeviceRequest];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -145,7 +145,7 @@ export class MSC4108SignInWithQR {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (this.ourIntent === QrCodeMode.Reciprocate && this.client) {
|
if (this.ourIntent === QrCodeMode.Reciprocate && this.client) {
|
||||||
this._code = await this.channel.generateCode(this.ourIntent, this.client.getHomeserverUrl());
|
this._code = await this.channel.generateCode(this.ourIntent, this.client.getDomain()!);
|
||||||
} else if (this.ourIntent === QrCodeMode.Login) {
|
} else if (this.ourIntent === QrCodeMode.Login) {
|
||||||
this._code = await this.channel.generateCode(this.ourIntent);
|
this._code = await this.channel.generateCode(this.ourIntent);
|
||||||
}
|
}
|
||||||
@@ -171,7 +171,7 @@ export class MSC4108SignInWithQR {
|
|||||||
* The scanning device has to discover the homeserver details, if they scanned the code then they already have it.
|
* The scanning device has to discover the homeserver details, if they scanned the code then they already have it.
|
||||||
* If the new device is the one rendering the QR code then it has to wait be sent the homeserver details via the rendezvous channel.
|
* If the new device is the one rendering the QR code then it has to wait be sent the homeserver details via the rendezvous channel.
|
||||||
*/
|
*/
|
||||||
public async negotiateProtocols(): Promise<{ homeserverBaseUrl?: string }> {
|
public async negotiateProtocols(): Promise<{ serverName?: string }> {
|
||||||
logger.info(`negotiateProtocols(isNewDevice=${this.isNewDevice} didScanCode=${this.didScanCode})`);
|
logger.info(`negotiateProtocols(isNewDevice=${this.isNewDevice} didScanCode=${this.didScanCode})`);
|
||||||
await this.channel.connect();
|
await this.channel.connect();
|
||||||
|
|
||||||
@@ -194,7 +194,7 @@ export class MSC4108SignInWithQR {
|
|||||||
await this.send<ProtocolsPayload>({
|
await this.send<ProtocolsPayload>({
|
||||||
type: PayloadType.Protocols,
|
type: PayloadType.Protocols,
|
||||||
protocols: ["device_authorization_grant"],
|
protocols: ["device_authorization_grant"],
|
||||||
homeserver: this.client?.getHomeserverUrl() ?? "",
|
homeserver: this.client!.getDomain()!,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
await this.send<FailurePayload>({
|
await this.send<FailurePayload>({
|
||||||
@@ -227,7 +227,7 @@ export class MSC4108SignInWithQR {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return { homeserverBaseUrl: payload.homeserver };
|
return { serverName: payload.homeserver };
|
||||||
} else {
|
} else {
|
||||||
// MSC4108-Flow: NewScanned - nothing to do
|
// MSC4108-Flow: NewScanned - nothing to do
|
||||||
}
|
}
|
||||||
|
@@ -54,11 +54,11 @@ export class MSC4108SecureChannel {
|
|||||||
/**
|
/**
|
||||||
* Generate a QR code for the current session.
|
* Generate a QR code for the current session.
|
||||||
* @param mode the mode to generate the QR code in, either `Login` or `Reciprocate`.
|
* @param mode the mode to generate the QR code in, either `Login` or `Reciprocate`.
|
||||||
* @param homeserverBaseUrl the base URL of the homeserver to connect to, required for `Reciprocate` mode.
|
* @param serverName the name of the homeserver to connect to, as defined by server discovery in the spec, required for `Reciprocate` mode.
|
||||||
*/
|
*/
|
||||||
public async generateCode(mode: QrCodeMode.Login): Promise<Uint8Array>;
|
public async generateCode(mode: QrCodeMode.Login): Promise<Uint8Array>;
|
||||||
public async generateCode(mode: QrCodeMode.Reciprocate, homeserverBaseUrl: string): Promise<Uint8Array>;
|
public async generateCode(mode: QrCodeMode.Reciprocate, serverName: string): Promise<Uint8Array>;
|
||||||
public async generateCode(mode: QrCodeMode, homeserverBaseUrl?: string): Promise<Uint8Array> {
|
public async generateCode(mode: QrCodeMode, serverName?: string): Promise<Uint8Array> {
|
||||||
const { url } = this.rendezvousSession;
|
const { url } = this.rendezvousSession;
|
||||||
|
|
||||||
if (!url) {
|
if (!url) {
|
||||||
@@ -68,8 +68,8 @@ export class MSC4108SecureChannel {
|
|||||||
return new QrCodeData(
|
return new QrCodeData(
|
||||||
this.secureChannel.public_key(),
|
this.secureChannel.public_key(),
|
||||||
url,
|
url,
|
||||||
mode === QrCodeMode.Reciprocate ? homeserverBaseUrl : undefined,
|
mode === QrCodeMode.Reciprocate ? serverName : undefined,
|
||||||
).to_bytes();
|
).toBytes();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -1100,10 +1100,9 @@ export class RustCrypto extends TypedEventEmitter<RustCryptoEvents, RustCryptoEv
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const [request, outgoingRequest]: [RustSdkCryptoJs.VerificationRequest, RustSdkCryptoJs.ToDeviceRequest] =
|
const [request, outgoingRequest] = device.requestVerification(
|
||||||
await device.requestVerification(
|
this._supportedVerificationMethods.map(verificationMethodIdentifierToMethod),
|
||||||
this._supportedVerificationMethods.map(verificationMethodIdentifierToMethod),
|
);
|
||||||
);
|
|
||||||
await this.outgoingRequestProcessor.makeOutgoingRequest(outgoingRequest);
|
await this.outgoingRequestProcessor.makeOutgoingRequest(outgoingRequest);
|
||||||
return new RustVerificationRequest(
|
return new RustVerificationRequest(
|
||||||
this.olmMachine,
|
this.olmMachine,
|
||||||
|
@@ -1925,10 +1925,10 @@
|
|||||||
"@jridgewell/resolve-uri" "^3.1.0"
|
"@jridgewell/resolve-uri" "^3.1.0"
|
||||||
"@jridgewell/sourcemap-codec" "^1.4.14"
|
"@jridgewell/sourcemap-codec" "^1.4.14"
|
||||||
|
|
||||||
"@matrix-org/matrix-sdk-crypto-wasm@^5.0.0":
|
"@matrix-org/matrix-sdk-crypto-wasm@^6.0.0":
|
||||||
version "5.0.0"
|
version "6.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/@matrix-org/matrix-sdk-crypto-wasm/-/matrix-sdk-crypto-wasm-5.0.0.tgz#f45a7bccaad218c05bcf9e7c8ca783c9d9a07af4"
|
resolved "https://registry.yarnpkg.com/@matrix-org/matrix-sdk-crypto-wasm/-/matrix-sdk-crypto-wasm-6.0.0.tgz#5e62ff07ee85a2e1b766a116683b7715a5e70c03"
|
||||||
integrity sha512-37ASjCKSTU5ycGfkP+LUXG4Ok6OAf6vE+1qU6uwWhe6FwadCS3vVWzJYd/3d9BQFwsx4GhFTIAXrW4iLG85rmQ==
|
integrity sha512-VVXfkIX2qr5Lz8EEUqsv/RBs0hZYoD1TyvtnaaNHW+2WaBo+TXu6Kpz2cQBNvRQbR3GhxDa/ZyQUxZYotORLWg==
|
||||||
|
|
||||||
"@matrix-org/olm@3.2.15":
|
"@matrix-org/olm@3.2.15":
|
||||||
version "3.2.15"
|
version "3.2.15"
|
||||||
|
Reference in New Issue
Block a user