mirror of
https://github.com/signalapp/Signal-Desktop.git
synced 2026-05-08 08:58:38 +01:00
Support for joining New Groups via invite links
This commit is contained in:
@@ -22,6 +22,8 @@ import { makeLookup } from './makeLookup';
|
||||
import { missingCaseError } from './missingCaseError';
|
||||
import { parseRemoteClientExpiration } from './parseRemoteClientExpiration';
|
||||
import { sleep } from './sleep';
|
||||
import { longRunningTaskWrapper } from './longRunningTaskWrapper';
|
||||
import { toWebSafeBase64, fromWebSafeBase64 } from './webSafeBase64';
|
||||
import * as zkgroup from './zkgroup';
|
||||
|
||||
export {
|
||||
@@ -31,6 +33,7 @@ export {
|
||||
createWaitBatcher,
|
||||
deleteForEveryone,
|
||||
downloadAttachment,
|
||||
fromWebSafeBase64,
|
||||
generateSecurityNumber,
|
||||
getSafetyNumberPlaceholder,
|
||||
getStringForProfileChange,
|
||||
@@ -39,10 +42,12 @@ export {
|
||||
GoogleChrome,
|
||||
hasExpired,
|
||||
isFileDangerous,
|
||||
longRunningTaskWrapper,
|
||||
makeLookup,
|
||||
missingCaseError,
|
||||
parseRemoteClientExpiration,
|
||||
Registration,
|
||||
sleep,
|
||||
toWebSafeBase64,
|
||||
zkgroup,
|
||||
};
|
||||
|
||||
@@ -14478,7 +14478,7 @@
|
||||
"rule": "DOM-innerHTML",
|
||||
"path": "ts/components/CompositionArea.js",
|
||||
"line": " el.innerHTML = '';",
|
||||
"lineNumber": 41,
|
||||
"lineNumber": 42,
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2020-05-20T20:10:43.540Z",
|
||||
"reasonDetail": "Our code, no user input, only clearing out the dom"
|
||||
@@ -14487,7 +14487,7 @@
|
||||
"rule": "React-useRef",
|
||||
"path": "ts/components/CompositionArea.js",
|
||||
"line": " const inputApiRef = React.useRef();",
|
||||
"lineNumber": 59,
|
||||
"lineNumber": 62,
|
||||
"reasonCategory": "falseMatch",
|
||||
"updated": "2020-10-26T19:12:24.410Z",
|
||||
"reasonDetail": "Doesn't refer to a DOM element."
|
||||
@@ -14496,7 +14496,7 @@
|
||||
"rule": "React-useRef",
|
||||
"path": "ts/components/CompositionArea.js",
|
||||
"line": " const attSlotRef = React.useRef(null);",
|
||||
"lineNumber": 82,
|
||||
"lineNumber": 85,
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2020-10-26T19:12:24.410Z",
|
||||
"reasonDetail": "Needed for the composition area."
|
||||
@@ -14505,7 +14505,7 @@
|
||||
"rule": "React-useRef",
|
||||
"path": "ts/components/CompositionArea.js",
|
||||
"line": " const micCellRef = React.useRef(null);",
|
||||
"lineNumber": 116,
|
||||
"lineNumber": 119,
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2020-10-26T19:12:24.410Z",
|
||||
"reasonDetail": "Needed for the composition area."
|
||||
@@ -14514,7 +14514,7 @@
|
||||
"rule": "DOM-innerHTML",
|
||||
"path": "ts/components/CompositionArea.tsx",
|
||||
"line": " el.innerHTML = '';",
|
||||
"lineNumber": 92,
|
||||
"lineNumber": 98,
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2020-06-03T19:23:21.195Z",
|
||||
"reasonDetail": "Our code, no user input, only clearing out the dom"
|
||||
@@ -15279,7 +15279,7 @@
|
||||
"rule": "jQuery-wrap(",
|
||||
"path": "ts/textsecure/WebAPI.js",
|
||||
"line": " const byteBuffer = window.dcodeIO.ByteBuffer.wrap(quote, 'binary', window.dcodeIO.ByteBuffer.LITTLE_ENDIAN);",
|
||||
"lineNumber": 1270,
|
||||
"lineNumber": 1302,
|
||||
"reasonCategory": "falseMatch",
|
||||
"updated": "2020-09-08T23:07:22.682Z"
|
||||
},
|
||||
@@ -15287,7 +15287,7 @@
|
||||
"rule": "jQuery-wrap(",
|
||||
"path": "ts/textsecure/WebAPI.ts",
|
||||
"line": " const byteBuffer = window.dcodeIO.ByteBuffer.wrap(",
|
||||
"lineNumber": 2174,
|
||||
"lineNumber": 2230,
|
||||
"reasonCategory": "falseMatch",
|
||||
"updated": "2020-09-08T23:07:22.682Z"
|
||||
},
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
export async function longRunningTaskWrapper<T>({
|
||||
name,
|
||||
idForLogging,
|
||||
task,
|
||||
suppressErrorDialog,
|
||||
}: {
|
||||
name: string;
|
||||
idForLogging: string;
|
||||
task: () => Promise<T>;
|
||||
suppressErrorDialog?: boolean;
|
||||
}): Promise<T> {
|
||||
const idLog = `${name}/${idForLogging}`;
|
||||
const ONE_SECOND = 1000;
|
||||
const TWO_SECONDS = 2000;
|
||||
|
||||
let progressView: typeof Whisper.ReactWrapperView | undefined;
|
||||
let spinnerStart;
|
||||
let progressTimeout: NodeJS.Timeout | undefined = setTimeout(() => {
|
||||
window.log.info(`longRunningTaskWrapper/${idLog}: Creating spinner`);
|
||||
|
||||
// Note: this component uses a portal to render itself into the top-level DOM. No
|
||||
// need to attach it to the DOM here.
|
||||
progressView = new Whisper.ReactWrapperView({
|
||||
className: 'progress-modal-wrapper',
|
||||
Component: window.Signal.Components.ProgressModal,
|
||||
});
|
||||
spinnerStart = Date.now();
|
||||
}, TWO_SECONDS);
|
||||
|
||||
// Note: any task we put here needs to have its own safety valve; this function will
|
||||
// show a spinner until it's done
|
||||
try {
|
||||
window.log.info(`longRunningTaskWrapper/${idLog}: Starting task`);
|
||||
const result = await task();
|
||||
window.log.info(
|
||||
`longRunningTaskWrapper/${idLog}: Task completed successfully`
|
||||
);
|
||||
|
||||
if (progressTimeout) {
|
||||
clearTimeout(progressTimeout);
|
||||
progressTimeout = undefined;
|
||||
}
|
||||
if (progressView) {
|
||||
const now = Date.now();
|
||||
if (spinnerStart && now - spinnerStart < ONE_SECOND) {
|
||||
window.log.info(
|
||||
`longRunningTaskWrapper/${idLog}: Spinner shown for less than second, showing for another second`
|
||||
);
|
||||
await window.Signal.Util.sleep(ONE_SECOND);
|
||||
}
|
||||
progressView.remove();
|
||||
progressView = undefined;
|
||||
}
|
||||
|
||||
return result;
|
||||
} catch (error) {
|
||||
window.log.error(
|
||||
`longRunningTaskWrapper/${idLog}: Error!`,
|
||||
error && error.stack ? error.stack : error
|
||||
);
|
||||
|
||||
if (progressTimeout) {
|
||||
clearTimeout(progressTimeout);
|
||||
progressTimeout = undefined;
|
||||
}
|
||||
if (progressView) {
|
||||
progressView.remove();
|
||||
progressView = undefined;
|
||||
}
|
||||
|
||||
if (!suppressErrorDialog) {
|
||||
window.log.info(`longRunningTaskWrapper/${idLog}: Showing error dialog`);
|
||||
|
||||
// Note: this component uses a portal to render itself into the top-level DOM. No
|
||||
// need to attach it to the DOM here.
|
||||
const errorView = new Whisper.ReactWrapperView({
|
||||
className: 'error-modal-wrapper',
|
||||
Component: window.Signal.Components.ErrorModal,
|
||||
props: {
|
||||
onClose: () => errorView.remove(),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
+6
-2
@@ -25,7 +25,7 @@ export function isSgnlHref(value: string | URL, logger: LoggerType): boolean {
|
||||
|
||||
type ParsedSgnlHref =
|
||||
| { command: null; args: Map<never, never> }
|
||||
| { command: string; args: Map<string, string> };
|
||||
| { command: string; args: Map<string, string>; hash: string | undefined };
|
||||
export function parseSgnlHref(
|
||||
href: string,
|
||||
logger: LoggerType
|
||||
@@ -42,5 +42,9 @@ export function parseSgnlHref(
|
||||
}
|
||||
});
|
||||
|
||||
return { command: url.host, args };
|
||||
return {
|
||||
command: url.host,
|
||||
args,
|
||||
hash: url.hash ? url.hash.slice(1) : undefined,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
export function toWebSafeBase64(base64: string): string {
|
||||
return base64.replace(/\//g, '_').replace(/\+/g, '-').replace(/=/g, '');
|
||||
}
|
||||
|
||||
export function fromWebSafeBase64(webSafeBase64: string): string {
|
||||
const base64 = webSafeBase64.replace(/_/g, '/').replace(/-/g, '+');
|
||||
|
||||
// Ensure that the character count is a multiple of four, filling in the extra
|
||||
// space needed with '='
|
||||
const remainder = base64.length % 4;
|
||||
if (remainder === 3) {
|
||||
return `${base64}=`;
|
||||
}
|
||||
if (remainder === 2) {
|
||||
return `${base64}==`;
|
||||
}
|
||||
if (remainder === 1) {
|
||||
return `${base64}===`;
|
||||
}
|
||||
|
||||
return base64;
|
||||
}
|
||||
Reference in New Issue
Block a user