Typed res
This commit is contained in:
@@ -4,7 +4,10 @@ import { boxSeal } from "@/base/crypto";
|
||||
import log from "@/base/log";
|
||||
import type { Collection } from "@/media/collection";
|
||||
import { photosDialogZIndex } from "@/new/photos/components/utils/z-index";
|
||||
import castGateway, { revokeAllCastTokens } from "@/new/photos/services/cast";
|
||||
import castGateway, {
|
||||
publicKeyForPairingCode,
|
||||
revokeAllCastTokens,
|
||||
} from "@/new/photos/services/cast";
|
||||
import { loadCast } from "@/new/photos/utils/chromecast-sender";
|
||||
import SingleInputForm, {
|
||||
type SingleInputFormProps,
|
||||
@@ -52,36 +55,34 @@ export const AlbumCastDialog: React.FC<AlbumCastDialogProps> = ({
|
||||
setFieldError,
|
||||
) => {
|
||||
try {
|
||||
await doCast(value.trim());
|
||||
onClose();
|
||||
} catch (e) {
|
||||
if (e instanceof Error && e.message == "tv-not-found") {
|
||||
setFieldError(t("tv_not_found"));
|
||||
if (await doCast(value.trim())) {
|
||||
onClose();
|
||||
} else {
|
||||
setFieldError(t("generic_error_retry"));
|
||||
setFieldError(t("tv_not_found"));
|
||||
}
|
||||
} catch (e) {
|
||||
log.error("Failed to cast", e);
|
||||
setFieldError(t("generic_error_retry"));
|
||||
}
|
||||
};
|
||||
|
||||
const doCast = async (pin: string) => {
|
||||
// Does the TV exist? have they advertised their existence?
|
||||
const tvPublicKeyB64 = await castGateway.getPublicKey(pin);
|
||||
if (!tvPublicKeyB64) {
|
||||
throw new Error("tv-not-found");
|
||||
}
|
||||
// Find out the public key associated with the given pairing code (if
|
||||
// indeed a device has published one).
|
||||
const publicKey = await publicKeyForPairingCode(pin);
|
||||
if (!publicKey) return false;
|
||||
|
||||
// Generate random id.
|
||||
const castToken = uuidv4();
|
||||
|
||||
// Ok, they exist. let's give them the good stuff.
|
||||
// Publish the payload so that the other end can use it.
|
||||
const payload = JSON.stringify({
|
||||
castToken: castToken,
|
||||
collectionID: collection.id,
|
||||
collectionKey: collection.key,
|
||||
});
|
||||
const encryptedPayload = await boxSeal(btoa(payload), tvPublicKeyB64);
|
||||
const encryptedPayload = await boxSeal(btoa(payload), publicKey);
|
||||
|
||||
// Hey TV, we acknowlege you!
|
||||
await castGateway.publishCastPayload(
|
||||
pin,
|
||||
encryptedPayload,
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import { authenticatedRequestHeaders } from "@/base/http";
|
||||
import log from "@/base/log";
|
||||
import { authenticatedRequestHeaders, ensureOk } from "@/base/http";
|
||||
import { apiURL } from "@/base/origins";
|
||||
import { ApiError } from "@ente/shared/error";
|
||||
import HTTPService from "@ente/shared/network/HTTPService";
|
||||
import { getToken } from "@ente/shared/storage/localStorage/helpers";
|
||||
import { z } from "zod";
|
||||
|
||||
/**
|
||||
* Revoke all existing outstanding cast tokens for the current user on remote.
|
||||
@@ -14,28 +13,22 @@ export const revokeAllCastTokens = async () =>
|
||||
headers: await authenticatedRequestHeaders(),
|
||||
});
|
||||
|
||||
class CastGateway {
|
||||
public async getPublicKey(code: string): Promise<string> {
|
||||
let resp;
|
||||
try {
|
||||
const token = getToken();
|
||||
resp = await HTTPService.get(
|
||||
await apiURL(`/cast/device-info/${code}`),
|
||||
undefined,
|
||||
{
|
||||
"X-Auth-Token": token,
|
||||
},
|
||||
);
|
||||
} catch (e) {
|
||||
if (e instanceof ApiError && e.httpStatusCode === 404) {
|
||||
return "";
|
||||
}
|
||||
log.error("failed to getPublicKey", e);
|
||||
throw e;
|
||||
}
|
||||
return resp.data.publicKey;
|
||||
}
|
||||
/**
|
||||
* Fetch the public key (represented as a base64 string) associated with the
|
||||
* given device / pairing {@link code} from remote, or `undefined` if there is
|
||||
* no public key associated with the given code.
|
||||
*/
|
||||
export const publicKeyForPairingCode = async (code: string) => {
|
||||
const res = await fetch(await apiURL(`/cast/device-info/${code}`), {
|
||||
headers: await authenticatedRequestHeaders(),
|
||||
});
|
||||
if (res.status == 404) return undefined;
|
||||
ensureOk(res);
|
||||
return z.object({ publicKey: z.string() }).parse(await res.json())
|
||||
.publicKey;
|
||||
};
|
||||
|
||||
class CastGateway {
|
||||
public async publishCastPayload(
|
||||
code: string,
|
||||
castPayload: string,
|
||||
|
||||
Reference in New Issue
Block a user