feat: only send token to TV

This commit is contained in:
httpjamesm 2024-01-06 00:00:12 -05:00
parent 72ed8b0497
commit e3b4d3a35e
No known key found for this signature in database
8 changed files with 17 additions and 296 deletions

View file

@ -1,8 +1,7 @@
import { getEndpoint } from 'utils/common/apiUtil';
import { getData, LS_KEYS } from 'utils/storage/localStorage'; import { getData, LS_KEYS } from 'utils/storage/localStorage';
import localForage from 'utils/storage/localForage'; import localForage from 'utils/storage/localForage';
import { getActualKey } from '@ente/shared/user';
import { getActualKey, getToken } from 'utils/common/key'; import { batch } from '@ente/shared/batch';
import { getPublicKey } from './userService'; import { getPublicKey } from './userService';
import HTTPService from './HTTPService'; import HTTPService from './HTTPService';
import { EnteFile } from 'types/file'; import { EnteFile } from 'types/file';
@ -67,10 +66,11 @@ import {
import ComlinkCryptoWorker from 'utils/comlink/ComlinkCryptoWorker'; import ComlinkCryptoWorker from 'utils/comlink/ComlinkCryptoWorker';
import { getLocalFiles } from './fileService'; import { getLocalFiles } from './fileService';
import { REQUEST_BATCH_SIZE } from 'constants/api'; import { REQUEST_BATCH_SIZE } from 'constants/api';
import { batch } from 'utils/common';
import { t } from 'i18next'; import { t } from 'i18next';
import { EncryptedMagicMetadata } from 'types/magicMetadata'; import { EncryptedMagicMetadata } from 'types/magicMetadata';
import { VISIBILITY_STATE } from 'types/magicMetadata'; import { VISIBILITY_STATE } from 'types/magicMetadata';
import { getEndpoint } from '@ente/shared/network/api';
import { getToken } from '@ente/shared/storage/localStorage/helpers';
const ENDPOINT = getEndpoint(); const ENDPOINT = getEndpoint();
const COLLECTION_TABLE = 'collections'; const COLLECTION_TABLE = 'collections';

View file

@ -1,113 +0,0 @@
import { getData, LS_KEYS } from 'utils/storage/localStorage';
export const getEndpoint = () => {
let endpoint = getData(LS_KEYS.API_ENDPOINT);
if (endpoint) {
return endpoint;
}
endpoint = process.env.NEXT_PUBLIC_ENTE_ENDPOINT;
if (isDevDeployment() && endpoint) {
return endpoint;
}
return 'https://api.ente.io';
};
export const getFileURL = (id: number) => {
const endpoint = process.env.NEXT_PUBLIC_ENTE_ENDPOINT;
if (isDevDeployment() && endpoint) {
return `${endpoint}/files/download/${id}`;
}
return `https://files.ente.io/?fileID=${id}`;
};
export const getPublicCollectionFileURL = (id: number) => {
const endpoint = process.env.NEXT_PUBLIC_ENTE_ENDPOINT;
if (isDevDeployment() && endpoint) {
return `${endpoint}/public-collection/files/download/${id}`;
}
return `https://public-albums.ente.io/download/?fileID=${id}`;
};
export const getThumbnailURL = (id: number) => {
const endpoint = process.env.NEXT_PUBLIC_ENTE_ENDPOINT;
if (isDevDeployment() && endpoint) {
return `${endpoint}/files/preview/${id}`;
}
return `https://thumbnails.ente.io/?fileID=${id}`;
};
export const getPublicCollectionThumbnailURL = (id: number) => {
const endpoint = process.env.NEXT_PUBLIC_ENTE_ENDPOINT;
if (isDevDeployment() && endpoint) {
return `${endpoint}/public-collection/files/preview/${id}`;
}
return `https://public-albums.ente.io/preview/?fileID=${id}`;
};
export const getUploadEndpoint = () => {
const endpoint = process.env.NEXT_PUBLIC_ENTE_UPLOAD_ENDPOINT;
if (isDevDeployment() && endpoint) {
return endpoint;
}
return `https://uploader.ente.io`;
};
export const getPaymentsURL = () => {
const paymentsURL = process.env.NEXT_PUBLIC_ENTE_PAYMENT_ENDPOINT;
if (isDevDeployment() && paymentsURL) {
return paymentsURL;
}
return `https://payments.ente.io`;
};
export const getAlbumsURL = () => {
const albumsURL = process.env.NEXT_PUBLIC_ENTE_ALBUM_ENDPOINT;
if (isDevDeployment() && albumsURL) {
return albumsURL;
}
return `https://albums.ente.io`;
};
// getFamilyPortalURL returns the endpoint for the family dashboard which can be used to
// create or manage family.
export const getFamilyPortalURL = () => {
const familyURL = process.env.NEXT_PUBLIC_ENTE_FAMILY_PORTAL_ENDPOINT;
if (isDevDeployment() && familyURL) {
return familyURL;
}
return `https://family.ente.io`;
};
// getAuthenticatorURL returns the endpoint for the authenticator which can be used to
// view authenticator codes.
export const getAuthURL = () => {
const authURL = process.env.NEXT_PUBLIC_ENTE_AUTH_ENDPOINT;
if (isDevDeployment() && authURL) {
return authURL;
}
return `https://auth.ente.io`;
};
export const getSentryTunnelURL = () => {
return `https://sentry-reporter.ente.io`;
};
/*
It's a dev deployment (and should use the environment override for endpoints ) in three cases:
1. when the URL opened is that of the staging web app, or
2. when the URL opened is that of the staging album app, or
3. if the app is running locally (hence node_env is development)
4. if the app is running in test mode
*/
export const isDevDeployment = () => {
if (globalThis?.location) {
return (
process.env.NEXT_PUBLIC_ENTE_WEB_ENDPOINT ===
globalThis.location.origin ||
process.env.NEXT_PUBLIC_ENTE_ALBUM_ENDPOINT ===
globalThis.location.origin ||
process.env.NEXT_PUBLIC_IS_TEST_APP === 'true' ||
process.env.NODE_ENV === 'development'
);
}
};

View file

@ -1,149 +0,0 @@
import { CustomError } from 'utils/error';
import isElectron from 'is-electron';
import { APP_DOWNLOAD_URL } from 'constants/urls';
export function checkConnectivity() {
if (navigator.onLine) {
return true;
}
throw new Error(CustomError.NO_INTERNET_CONNECTION);
}
export function runningInBrowser() {
return typeof window !== 'undefined';
}
export function runningInWorker() {
return typeof importScripts === 'function';
}
export function runningInElectron() {
return isElectron();
}
export function runningInChrome(includeMobile: boolean) {
try {
const userAgentData = navigator['userAgentData'];
const chromeBrand = userAgentData?.brands?.filter(
(b) => b.brand === 'Google Chrome' || b.brand === 'Chromium'
)?.[0];
return chromeBrand && (includeMobile || userAgentData.mobile === false);
} catch (error) {
console.error('Error in runningInChrome: ', error);
return false;
}
}
export function offscreenCanvasSupported() {
return !(typeof OffscreenCanvas === 'undefined');
}
export function webglSupported() {
try {
const canvas = document.createElement('canvas');
const gl = canvas.getContext('webgl');
return gl && gl instanceof WebGLRenderingContext;
} catch (error) {
console.error('Error in webglSupported: ', error);
return false;
}
}
export async function sleep(time: number) {
await new Promise((resolve) => {
setTimeout(() => resolve(null), time);
});
}
export function downloadApp() {
openLink(APP_DOWNLOAD_URL, true);
}
export function reverseString(title: string) {
return title
?.split(' ')
.reduce((reversedString, currWord) => `${currWord} ${reversedString}`);
}
export function initiateEmail(email: string) {
const a = document.createElement('a');
a.href = 'mailto:' + email;
a.rel = 'noreferrer noopener';
a.click();
}
export const promiseWithTimeout = async <T>(
request: Promise<T>,
timeout: number
): Promise<T> => {
const timeoutRef = { current: null };
const rejectOnTimeout = new Promise<null>((_, reject) => {
timeoutRef.current = setTimeout(
() => reject(Error(CustomError.WAIT_TIME_EXCEEDED)),
timeout
);
});
const requestWithTimeOutCancellation = async () => {
const resp = await request;
clearTimeout(timeoutRef.current);
return resp;
};
return await Promise.race([
requestWithTimeOutCancellation(),
rejectOnTimeout,
]);
};
export const preloadImage = (imgBasePath: string) => {
const srcSet = [];
for (let i = 1; i <= 3; i++) {
srcSet.push(`${imgBasePath}/${i}x.png ${i}x`);
}
new Image().srcset = srcSet.join(',');
};
export function openLink(href: string, newTab?: boolean) {
const a = document.createElement('a');
a.href = href;
if (newTab) {
a.target = '_blank';
}
a.rel = 'noreferrer noopener';
a.click();
}
export async function waitAndRun(
waitPromise: Promise<void>,
task: () => Promise<void>
) {
if (waitPromise && isPromise(waitPromise)) {
await waitPromise;
}
await task();
}
function isPromise(p: any) {
if (typeof p === 'object' && typeof p.then === 'function') {
return true;
}
return false;
}
export function isClipboardItemPresent() {
return typeof ClipboardItem !== 'undefined';
}
export function batch<T>(arr: T[], batchSize: number): T[][] {
const batches: T[][] = [];
for (let i = 0; i < arr.length; i += batchSize) {
batches.push(arr.slice(i, i + batchSize));
}
return batches;
}
export const mergeMaps = <K, V>(map1: Map<K, V>, map2: Map<K, V>) => {
const mergedMap = new Map<K, V>(map1);
map2.forEach((value, key) => {
mergedMap.set(key, value);
});
return mergedMap;
};

View file

@ -1,26 +0,0 @@
import { B64EncryptionResult } from 'types/crypto';
import ComlinkCryptoWorker from 'utils/comlink/ComlinkCryptoWorker';
import { getData, LS_KEYS } from 'utils/storage/localStorage';
import { getKey, SESSION_KEYS } from 'utils/storage/sessionStorage';
import { CustomError } from '../error';
export const getActualKey = async () => {
try {
const encryptionKeyAttributes: B64EncryptionResult = getKey(
SESSION_KEYS.ENCRYPTION_KEY
);
const cryptoWorker = await ComlinkCryptoWorker.getInstance();
const key = await cryptoWorker.decryptB64(
encryptionKeyAttributes.encryptedData,
encryptionKeyAttributes.nonce,
encryptionKeyAttributes.key
);
return key;
} catch (e) {
throw new Error(CustomError.KEY_MISSING);
}
};
export const getToken = () => getData(LS_KEYS.USER)?.token;
export const getUserID = () => getData(LS_KEYS.USER)?.id;

View file

@ -12,8 +12,8 @@ import EnteButton from '@ente/shared/components/EnteButton';
import EnteSpinner from '@ente/shared/components/EnteSpinner'; import EnteSpinner from '@ente/shared/components/EnteSpinner';
import { VerticallyCentered } from '@ente/shared/components/Container'; import { VerticallyCentered } from '@ente/shared/components/Container';
import { logError } from '@ente/shared/sentry'; import { logError } from '@ente/shared/sentry';
import { LS_KEYS, getData } from '@ente/shared/storage/localStorage';
import { Collection } from 'types/collection'; import { Collection } from 'types/collection';
import { getToken } from '@ente/shared/storage/localStorage/helpers';
interface Props { interface Props {
show: boolean; show: boolean;
@ -72,7 +72,7 @@ export default function AlbumCastDialog(props: Props) {
// ok, they exist. let's give them the good stuff. // ok, they exist. let's give them the good stuff.
const payload = JSON.stringify({ const payload = JSON.stringify({
user: JSON.stringify(getData(LS_KEYS.USER)), token: getToken(),
targetCollectionId: props.currentCollection.id, targetCollectionId: props.currentCollection.id,
targetCollectionKey: props.currentCollection.key, targetCollectionKey: props.currentCollection.key,
}); });

View file

@ -0,0 +1,7 @@
export function batch<T>(arr: T[], batchSize: number): T[][] {
const batches: T[][] = [];
for (let i = 0; i < arr.length; i += batchSize) {
batches.push(arr.slice(i, i + batchSize));
}
return batches;
}

View file

@ -3,9 +3,9 @@ import { LS_KEYS, getData, setData } from '.';
import { Language } from '@ente/shared/i18n/locale'; import { Language } from '@ente/shared/i18n/locale';
export const getToken = () => { export const getToken = () => {
const token = getData(LS_KEYS.USER)?.token; const token = getData(LS_KEYS.TOKEN) || getData(LS_KEYS.USER)?.token;
if (!token) { if (!token) {
throw Error(CustomError.TOKEN_MISSING); throw new Error(CustomError.TOKEN_MISSING);
} }
return token; return token;
}; };

View file

@ -2,6 +2,8 @@ import { logError } from '@ente/shared/sentry';
export enum LS_KEYS { export enum LS_KEYS {
USER = 'user', USER = 'user',
// ONLY RECOMMENDED FOR APPS LIKE CAST WHERE OTHER USER INFO ISN'T NECESSARY
TOKEN = 'token',
SESSION = 'session', SESSION = 'session',
KEY_ATTRIBUTES = 'keyAttributes', KEY_ATTRIBUTES = 'keyAttributes',
ORIGINAL_KEY_ATTRIBUTES = 'originalKeyAttributes', ORIGINAL_KEY_ATTRIBUTES = 'originalKeyAttributes',