Move sticker creator API to chat service
This commit is contained in:
parent
a1e090d1f1
commit
31cbb89b0d
21 changed files with 124 additions and 587 deletions
|
@ -3,7 +3,6 @@
|
|||
|
||||
import React from 'react';
|
||||
import type {
|
||||
AuthorizeArtCreatorDataType,
|
||||
ContactModalStateType,
|
||||
DeleteMessagesPropsType,
|
||||
EditHistoryMessagesType,
|
||||
|
@ -96,11 +95,6 @@ export type PropsType = {
|
|||
// UsernameOnboarding
|
||||
usernameOnboardingState: UsernameOnboardingState;
|
||||
renderUsernameOnboarding: () => JSX.Element;
|
||||
// AuthArtCreatorModal
|
||||
authArtCreatorData?: AuthorizeArtCreatorDataType;
|
||||
isAuthorizingArtCreator?: boolean;
|
||||
cancelAuthorizeArtCreator: () => unknown;
|
||||
confirmAuthorizeArtCreator: () => unknown;
|
||||
};
|
||||
|
||||
export function GlobalModalContainer({
|
||||
|
@ -166,11 +160,6 @@ export function GlobalModalContainer({
|
|||
// UsernameOnboarding
|
||||
usernameOnboardingState,
|
||||
renderUsernameOnboarding,
|
||||
// AuthArtCreatorModal
|
||||
authArtCreatorData,
|
||||
isAuthorizingArtCreator,
|
||||
cancelAuthorizeArtCreator,
|
||||
confirmAuthorizeArtCreator,
|
||||
}: PropsType): JSX.Element | null {
|
||||
// We want the following dialogs to show in this order:
|
||||
// 1. Errors
|
||||
|
@ -289,28 +278,5 @@ export function GlobalModalContainer({
|
|||
);
|
||||
}
|
||||
|
||||
if (authArtCreatorData) {
|
||||
return (
|
||||
<ConfirmationDialog
|
||||
dialogName="GlobalModalContainer.authArtCreator"
|
||||
cancelText={i18n('icu:AuthArtCreator--dialog--dismiss')}
|
||||
cancelButtonVariant={ButtonVariant.Secondary}
|
||||
i18n={i18n}
|
||||
isSpinning={isAuthorizingArtCreator}
|
||||
onClose={cancelAuthorizeArtCreator}
|
||||
actions={[
|
||||
{
|
||||
text: i18n('icu:AuthArtCreator--dialog--confirm'),
|
||||
style: 'affirmative',
|
||||
action: confirmAuthorizeArtCreator,
|
||||
autoClose: false,
|
||||
},
|
||||
]}
|
||||
>
|
||||
{i18n('icu:AuthArtCreator--dialog--message')}
|
||||
</ConfirmationDialog>
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -18,7 +18,6 @@ import type { RecipientsByConversation } from './stories';
|
|||
import type { SafetyNumberChangeSource } from '../../components/SafetyNumberChangeDialog';
|
||||
import type { EditState as ProfileEditorEditState } from '../../components/ProfileEditor';
|
||||
import type { StateType as RootStateType } from '../reducer';
|
||||
import * as Errors from '../../types/errors';
|
||||
import * as SingleServePromise from '../../services/singleServePromise';
|
||||
import * as Stickers from '../../types/Stickers';
|
||||
import { UsernameOnboardingState } from '../../types/globalModals';
|
||||
|
@ -28,18 +27,13 @@ import type { BoundActionCreatorsMapObject } from '../../hooks/useBoundActions';
|
|||
import { longRunningTaskWrapper } from '../../util/longRunningTaskWrapper';
|
||||
import { useBoundActions } from '../../hooks/useBoundActions';
|
||||
import { isGroupV1 } from '../../util/whatTypeOfConversation';
|
||||
import { authorizeArtCreator } from '../../textsecure/authorizeArtCreator';
|
||||
import type { AuthorizeArtCreatorOptionsType } from '../../textsecure/authorizeArtCreator';
|
||||
import { getGroupMigrationMembers } from '../../groups';
|
||||
import { ToastType } from '../../types/Toast';
|
||||
import {
|
||||
MESSAGE_CHANGED,
|
||||
MESSAGE_DELETED,
|
||||
MESSAGE_EXPIRED,
|
||||
actions as conversationsActions,
|
||||
} from './conversations';
|
||||
import { SHOW_TOAST } from './toast';
|
||||
import type { ShowToastActionType } from './toast';
|
||||
import { isDownloaded } from '../../types/Attachment';
|
||||
import type { ButtonVariant } from '../../components/Button';
|
||||
import type { MessageRequestState } from '../../components/conversation/MessageRequestActionsConfirmation';
|
||||
|
@ -73,8 +67,6 @@ export type SafetyNumberChangedBlockingDataType = ReadonlyDeep<{
|
|||
promiseUuid: SingleServePromise.SingleServePromiseIdString;
|
||||
source?: SafetyNumberChangeSource;
|
||||
}>;
|
||||
export type AuthorizeArtCreatorDataType =
|
||||
ReadonlyDeep<AuthorizeArtCreatorOptionsType>;
|
||||
|
||||
type MigrateToGV2PropsType = ReadonlyDeep<{
|
||||
areWeInvited: boolean;
|
||||
|
@ -87,7 +79,6 @@ type MigrateToGV2PropsType = ReadonlyDeep<{
|
|||
export type GlobalModalsStateType = ReadonlyDeep<{
|
||||
addUserToAnotherGroupModalContactId?: string;
|
||||
aboutContactModalContactId?: string;
|
||||
authArtCreatorData?: AuthorizeArtCreatorDataType;
|
||||
contactModalState?: ContactModalStateType;
|
||||
deleteMessagesProps?: DeleteMessagesPropsType;
|
||||
editHistoryMessages?: EditHistoryMessagesType;
|
||||
|
@ -100,7 +91,6 @@ export type GlobalModalsStateType = ReadonlyDeep<{
|
|||
forwardMessagesProps?: ForwardMessagesPropsType;
|
||||
gv2MigrationProps?: MigrateToGV2PropsType;
|
||||
hasConfirmationModal: boolean;
|
||||
isAuthorizingArtCreator?: boolean;
|
||||
isProfileEditorVisible: boolean;
|
||||
isShortcutGuideModalVisible: boolean;
|
||||
isSignalConnectionsVisible: boolean;
|
||||
|
@ -157,13 +147,7 @@ const TOGGLE_MESSAGE_REQUEST_ACTIONS_CONFIRMATION =
|
|||
'globalModals/TOGGLE_MESSAGE_REQUEST_ACTIONS_CONFIRMATION';
|
||||
const CLOSE_SHORTCUT_GUIDE_MODAL = 'globalModals/CLOSE_SHORTCUT_GUIDE_MODAL';
|
||||
const SHOW_SHORTCUT_GUIDE_MODAL = 'globalModals/SHOW_SHORTCUT_GUIDE_MODAL';
|
||||
const SHOW_AUTH_ART_CREATOR = 'globalModals/SHOW_AUTH_ART_CREATOR';
|
||||
const TOGGLE_CONFIRMATION_MODAL = 'globalModals/TOGGLE_CONFIRMATION_MODAL';
|
||||
const CANCEL_AUTH_ART_CREATOR = 'globalModals/CANCEL_AUTH_ART_CREATOR';
|
||||
const CONFIRM_AUTH_ART_CREATOR_PENDING =
|
||||
'globalModals/CONFIRM_AUTH_ART_CREATOR_PENDING';
|
||||
const CONFIRM_AUTH_ART_CREATOR_FULFILLED =
|
||||
'globalModals/CONFIRM_AUTH_ART_CREATOR_FULFILLED';
|
||||
const SHOW_EDIT_HISTORY_MODAL = 'globalModals/SHOW_EDIT_HISTORY_MODAL';
|
||||
const CLOSE_EDIT_HISTORY_MODAL = 'globalModals/CLOSE_EDIT_HISTORY_MODAL';
|
||||
const TOGGLE_USERNAME_ONBOARDING = 'globalModals/TOGGLE_USERNAME_ONBOARDING';
|
||||
|
@ -332,23 +316,6 @@ type ShowShortcutGuideModalActionType = ReadonlyDeep<{
|
|||
type: typeof SHOW_SHORTCUT_GUIDE_MODAL;
|
||||
}>;
|
||||
|
||||
export type ShowAuthArtCreatorActionType = ReadonlyDeep<{
|
||||
type: typeof SHOW_AUTH_ART_CREATOR;
|
||||
payload: AuthorizeArtCreatorDataType;
|
||||
}>;
|
||||
|
||||
type CancelAuthArtCreatorActionType = ReadonlyDeep<{
|
||||
type: typeof CANCEL_AUTH_ART_CREATOR;
|
||||
}>;
|
||||
|
||||
type ConfirmAuthArtCreatorPendingActionType = ReadonlyDeep<{
|
||||
type: typeof CONFIRM_AUTH_ART_CREATOR_PENDING;
|
||||
}>;
|
||||
|
||||
type ConfirmAuthArtCreatorFulfilledActionType = ReadonlyDeep<{
|
||||
type: typeof CONFIRM_AUTH_ART_CREATOR_FULFILLED;
|
||||
}>;
|
||||
|
||||
type ShowEditHistoryModalActionType = ReadonlyDeep<{
|
||||
type: typeof SHOW_EDIT_HISTORY_MODAL;
|
||||
payload: {
|
||||
|
@ -361,14 +328,11 @@ type CloseEditHistoryModalActionType = ReadonlyDeep<{
|
|||
}>;
|
||||
|
||||
export type GlobalModalsActionType = ReadonlyDeep<
|
||||
| CancelAuthArtCreatorActionType
|
||||
| CloseEditHistoryModalActionType
|
||||
| CloseErrorModalActionType
|
||||
| CloseGV2MigrationDialogActionType
|
||||
| CloseShortcutGuideModalActionType
|
||||
| CloseStickerPackPreviewActionType
|
||||
| ConfirmAuthArtCreatorFulfilledActionType
|
||||
| ConfirmAuthArtCreatorPendingActionType
|
||||
| HideContactModalActionType
|
||||
| HideSendAnywayDialogActiontype
|
||||
| HideStoriesSettingsActionType
|
||||
|
@ -377,7 +341,6 @@ export type GlobalModalsActionType = ReadonlyDeep<
|
|||
| MessageChangedActionType
|
||||
| MessageDeletedActionType
|
||||
| MessageExpiredActionType
|
||||
| ShowAuthArtCreatorActionType
|
||||
| ShowContactModalActionType
|
||||
| ShowEditHistoryModalActionType
|
||||
| ShowErrorModalActionType
|
||||
|
@ -406,19 +369,16 @@ export type GlobalModalsActionType = ReadonlyDeep<
|
|||
// Action Creators
|
||||
|
||||
export const actions = {
|
||||
cancelAuthorizeArtCreator,
|
||||
closeEditHistoryModal,
|
||||
closeErrorModal,
|
||||
closeGV2MigrationDialog,
|
||||
closeShortcutGuideModal,
|
||||
closeStickerPackPreview,
|
||||
confirmAuthorizeArtCreator,
|
||||
hideBlockingSafetyNumberChangeDialog,
|
||||
hideContactModal,
|
||||
hideStoriesSettings,
|
||||
hideUserNotFoundModal,
|
||||
hideWhatsNewModal,
|
||||
showAuthorizeArtCreator,
|
||||
showBlockingSafetyNumberChangeDialog,
|
||||
showContactModal,
|
||||
showEditHistoryModal,
|
||||
|
@ -790,25 +750,6 @@ function showShortcutGuideModal(): ShowShortcutGuideModalActionType {
|
|||
};
|
||||
}
|
||||
|
||||
function cancelAuthorizeArtCreator(): ThunkAction<
|
||||
void,
|
||||
RootStateType,
|
||||
unknown,
|
||||
CancelAuthArtCreatorActionType
|
||||
> {
|
||||
return async (dispatch, getState) => {
|
||||
const data = getState().globalModals.authArtCreatorData;
|
||||
|
||||
if (!data) {
|
||||
return;
|
||||
}
|
||||
|
||||
dispatch({
|
||||
type: CANCEL_AUTH_ART_CREATOR,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
function copyOverMessageAttributesIntoEditHistory(
|
||||
messageAttributes: ReadonlyDeep<MessageAttributesType>
|
||||
): EditHistoryMessagesType | undefined {
|
||||
|
@ -860,54 +801,6 @@ function closeEditHistoryModal(): CloseEditHistoryModalActionType {
|
|||
};
|
||||
}
|
||||
|
||||
export function showAuthorizeArtCreator(
|
||||
data: AuthorizeArtCreatorDataType
|
||||
): ShowAuthArtCreatorActionType {
|
||||
return {
|
||||
type: SHOW_AUTH_ART_CREATOR,
|
||||
payload: data,
|
||||
};
|
||||
}
|
||||
|
||||
export function confirmAuthorizeArtCreator(): ThunkAction<
|
||||
void,
|
||||
RootStateType,
|
||||
unknown,
|
||||
| ConfirmAuthArtCreatorPendingActionType
|
||||
| ConfirmAuthArtCreatorFulfilledActionType
|
||||
| CancelAuthArtCreatorActionType
|
||||
| ShowToastActionType
|
||||
> {
|
||||
return async (dispatch, getState) => {
|
||||
const data = getState().globalModals.authArtCreatorData;
|
||||
|
||||
if (!data) {
|
||||
dispatch({ type: CANCEL_AUTH_ART_CREATOR });
|
||||
return;
|
||||
}
|
||||
|
||||
dispatch({
|
||||
type: CONFIRM_AUTH_ART_CREATOR_PENDING,
|
||||
});
|
||||
|
||||
try {
|
||||
await authorizeArtCreator(data);
|
||||
} catch (err) {
|
||||
log.error('authorizeArtCreator failed', Errors.toLogFormat(err));
|
||||
dispatch({
|
||||
type: SHOW_TOAST,
|
||||
payload: {
|
||||
toastType: ToastType.Error,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
dispatch({
|
||||
type: CONFIRM_AUTH_ART_CREATOR_FULFILLED,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
function copyOverMessageAttributesIntoForwardMessages(
|
||||
messagesProps: ReadonlyArray<ForwardMessagePropsType>,
|
||||
attributes: ReadonlyDeep<MessageAttributesType>
|
||||
|
@ -1168,36 +1061,6 @@ export function reducer(
|
|||
};
|
||||
}
|
||||
|
||||
if (action.type === CANCEL_AUTH_ART_CREATOR) {
|
||||
return {
|
||||
...state,
|
||||
authArtCreatorData: undefined,
|
||||
};
|
||||
}
|
||||
|
||||
if (action.type === SHOW_AUTH_ART_CREATOR) {
|
||||
return {
|
||||
...state,
|
||||
isAuthorizingArtCreator: false,
|
||||
authArtCreatorData: action.payload,
|
||||
};
|
||||
}
|
||||
|
||||
if (action.type === CONFIRM_AUTH_ART_CREATOR_PENDING) {
|
||||
return {
|
||||
...state,
|
||||
isAuthorizingArtCreator: true,
|
||||
};
|
||||
}
|
||||
|
||||
if (action.type === CONFIRM_AUTH_ART_CREATOR_FULFILLED) {
|
||||
return {
|
||||
...state,
|
||||
isAuthorizingArtCreator: false,
|
||||
authArtCreatorData: undefined,
|
||||
};
|
||||
}
|
||||
|
||||
if (action.type === SHOW_EDIT_HISTORY_MODAL) {
|
||||
return {
|
||||
...state,
|
||||
|
|
|
@ -90,7 +90,6 @@ export const SmartGlobalModalContainer = memo(
|
|||
const {
|
||||
aboutContactModalContactId,
|
||||
addUserToAnotherGroupModalContactId,
|
||||
authArtCreatorData,
|
||||
contactModalState,
|
||||
deleteMessagesProps,
|
||||
editHistoryMessages,
|
||||
|
@ -99,7 +98,6 @@ export const SmartGlobalModalContainer = memo(
|
|||
forwardMessagesProps,
|
||||
messageRequestActionsConfirmationProps,
|
||||
notePreviewModalProps,
|
||||
isAuthorizingArtCreator,
|
||||
isProfileEditorVisible,
|
||||
isShortcutGuideModalVisible,
|
||||
isSignalConnectionsVisible,
|
||||
|
@ -113,9 +111,7 @@ export const SmartGlobalModalContainer = memo(
|
|||
} = useSelector(getGlobalModalsState);
|
||||
|
||||
const {
|
||||
cancelAuthorizeArtCreator,
|
||||
closeErrorModal,
|
||||
confirmAuthorizeArtCreator,
|
||||
hideUserNotFoundModal,
|
||||
hideWhatsNewModal,
|
||||
toggleSignalConnectionsModal,
|
||||
|
@ -218,10 +214,6 @@ export const SmartGlobalModalContainer = memo(
|
|||
toggleSignalConnectionsModal={toggleSignalConnectionsModal}
|
||||
userNotFoundModalState={userNotFoundModalState}
|
||||
usernameOnboardingState={usernameOnboardingState}
|
||||
isAuthorizingArtCreator={isAuthorizingArtCreator}
|
||||
authArtCreatorData={authArtCreatorData}
|
||||
cancelAuthorizeArtCreator={cancelAuthorizeArtCreator}
|
||||
confirmAuthorizeArtCreator={confirmAuthorizeArtCreator}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -142,16 +142,6 @@ describe('signalRoutes', () => {
|
|||
check(`sgnl://signal.link/call#key=${foo}`, result);
|
||||
});
|
||||
|
||||
it('artAuth', () => {
|
||||
const result: ParsedSignalRoute = {
|
||||
key: 'artAuth',
|
||||
args: { token: foo, pubKey: foo },
|
||||
};
|
||||
const check = createCheck({ hasWebUrl: false });
|
||||
check(`sgnl://art-auth/?token=${foo}&pub_key=${foo}`, result);
|
||||
check(`sgnl://art-auth?token=${foo}&pub_key=${foo}`, result);
|
||||
});
|
||||
|
||||
it('artAddStickers', () => {
|
||||
const result: ParsedSignalRoute = {
|
||||
key: 'artAddStickers',
|
||||
|
|
|
@ -52,7 +52,6 @@ export const AUTHENTICATED_CHANNEL_NAME = 'authenticated';
|
|||
|
||||
export type SocketManagerOptions = Readonly<{
|
||||
url: string;
|
||||
artCreatorUrl: string;
|
||||
certificateAuthority: string;
|
||||
version: string;
|
||||
proxyUrl?: string;
|
||||
|
|
|
@ -14,7 +14,6 @@ import PQueue from 'p-queue';
|
|||
import { v4 as getGuid } from 'uuid';
|
||||
import { z } from 'zod';
|
||||
import type { Readable } from 'stream';
|
||||
import type { connection as WebSocket } from 'websocket';
|
||||
|
||||
import { Net } from '@signalapp/libsignal-client';
|
||||
import { assertDev, strictAssert } from '../util/assert';
|
||||
|
@ -554,7 +553,6 @@ const URL_CALLS = {
|
|||
getOnboardingStoryManifest:
|
||||
'dynamic/desktop/stories/onboarding/manifest.json',
|
||||
getStickerPackUpload: 'v1/sticker/pack/form',
|
||||
getArtAuth: 'v1/art/auth',
|
||||
getBackupCredentials: 'v1/archives/auth',
|
||||
getBackupCDNCredentials: 'v1/archives/auth/read',
|
||||
getBackupUploadForm: 'v1/archives/upload/form',
|
||||
|
@ -647,7 +645,6 @@ type InitializeOptionsType = {
|
|||
storageUrl: string;
|
||||
updatesUrl: string;
|
||||
resourcesUrl: string;
|
||||
artCreatorUrl: string;
|
||||
cdnUrlObject: {
|
||||
readonly '0': string;
|
||||
readonly [propName: string]: string;
|
||||
|
@ -975,13 +972,6 @@ export type ReportMessageOptionsType = Readonly<{
|
|||
token?: string;
|
||||
}>;
|
||||
|
||||
const artAuthZod = z.object({
|
||||
username: z.string(),
|
||||
password: z.string(),
|
||||
});
|
||||
|
||||
export type ArtAuthType = z.infer<typeof artAuthZod>;
|
||||
|
||||
const attachmentV3Response = z.object({
|
||||
cdn: z.literal(2).or(z.literal(3)),
|
||||
key: z.string(),
|
||||
|
@ -1149,6 +1139,23 @@ export type GetBackupInfoResponseType = z.infer<
|
|||
typeof getBackupInfoResponseSchema
|
||||
>;
|
||||
|
||||
const StickerPackUploadAttributesSchema = z.object({
|
||||
acl: z.string(),
|
||||
algorithm: z.string(),
|
||||
credential: z.string(),
|
||||
date: z.string(),
|
||||
id: z.number(),
|
||||
key: z.string(),
|
||||
policy: z.string(),
|
||||
signature: z.string(),
|
||||
});
|
||||
|
||||
const StickerPackUploadFormSchema = z.object({
|
||||
packId: z.string(),
|
||||
manifest: StickerPackUploadAttributesSchema,
|
||||
stickers: z.array(StickerPackUploadAttributesSchema),
|
||||
});
|
||||
|
||||
export type WebAPIType = {
|
||||
startRegistration(): unknown;
|
||||
finishRegistration(baton: unknown): void;
|
||||
|
@ -1166,7 +1173,6 @@ export type WebAPIType = {
|
|||
version: string,
|
||||
imageFiles: Array<string>
|
||||
) => Promise<Array<Uint8Array>>;
|
||||
getArtAuth: () => Promise<ArtAuthType>;
|
||||
getAttachmentFromBackupTier: (args: {
|
||||
mediaId: string;
|
||||
backupDir: string;
|
||||
|
@ -1237,7 +1243,6 @@ export type WebAPIType = {
|
|||
getProvisioningResource: (
|
||||
handler: IRequestHandler
|
||||
) => Promise<IWebSocketResource>;
|
||||
getArtProvisioningSocket: (token: string) => Promise<WebSocket>;
|
||||
getSenderCertificate: (
|
||||
withUuid?: boolean
|
||||
) => Promise<GetSenderCertificateResultType>;
|
||||
|
@ -1280,7 +1285,7 @@ export type WebAPIType = {
|
|||
) => Promise<UploadAvatarHeadersType | undefined>;
|
||||
putStickers: (
|
||||
encryptedManifest: Uint8Array,
|
||||
encryptedStickers: Array<Uint8Array>,
|
||||
encryptedStickers: ReadonlyArray<Uint8Array>,
|
||||
onProgress?: () => void
|
||||
) => Promise<string>;
|
||||
reserveUsername: (
|
||||
|
@ -1471,7 +1476,6 @@ export function initialize({
|
|||
storageUrl,
|
||||
updatesUrl,
|
||||
resourcesUrl,
|
||||
artCreatorUrl,
|
||||
directoryConfig,
|
||||
cdnUrlObject,
|
||||
certificateAuthority,
|
||||
|
@ -1493,9 +1497,6 @@ export function initialize({
|
|||
if (!isString(resourcesUrl)) {
|
||||
throw new Error('WebAPI.initialize: Invalid updatesUrl (general)');
|
||||
}
|
||||
if (!isString(artCreatorUrl)) {
|
||||
throw new Error('WebAPI.initialize: Invalid artCreatorUrl');
|
||||
}
|
||||
if (!isObject(cdnUrlObject)) {
|
||||
throw new Error('WebAPI.initialize: Invalid cdnUrlObject');
|
||||
}
|
||||
|
@ -1558,7 +1559,6 @@ export function initialize({
|
|||
|
||||
const socketManager = new SocketManager(libsignalNet, {
|
||||
url,
|
||||
artCreatorUrl,
|
||||
certificateAuthority,
|
||||
version,
|
||||
proxyUrl,
|
||||
|
@ -1667,8 +1667,6 @@ export function initialize({
|
|||
fetchLinkPreviewMetadata,
|
||||
finishRegistration,
|
||||
getAccountForUsername,
|
||||
getArtAuth,
|
||||
getArtProvisioningSocket,
|
||||
getAttachment,
|
||||
getAttachmentFromBackupTier,
|
||||
getAvatar,
|
||||
|
@ -3309,20 +3307,19 @@ export function initialize({
|
|||
|
||||
async function putStickers(
|
||||
encryptedManifest: Uint8Array,
|
||||
encryptedStickers: Array<Uint8Array>,
|
||||
encryptedStickers: ReadonlyArray<Uint8Array>,
|
||||
onProgress?: () => void
|
||||
) {
|
||||
// Get manifest and sticker upload parameters
|
||||
const { packId, manifest, stickers } = (await _ajax({
|
||||
const formJson = await _ajax({
|
||||
call: 'getStickerPackUpload',
|
||||
responseType: 'json',
|
||||
httpType: 'GET',
|
||||
urlParameters: `/${encryptedStickers.length}`,
|
||||
})) as {
|
||||
packId: string;
|
||||
manifest: ServerV2AttachmentType;
|
||||
stickers: ReadonlyArray<ServerV2AttachmentType>;
|
||||
};
|
||||
});
|
||||
|
||||
const { packId, manifest, stickers } =
|
||||
StickerPackUploadFormSchema.parse(formJson);
|
||||
|
||||
// Upload manifest
|
||||
const manifestParams = makePutParams(manifest, encryptedManifest);
|
||||
|
@ -4008,15 +4005,6 @@ export function initialize({
|
|||
return socketManager.getProvisioningResource(handler);
|
||||
}
|
||||
|
||||
function getArtProvisioningSocket(token: string): Promise<WebSocket> {
|
||||
return socketManager.connectExternalSocket({
|
||||
url: `${artCreatorUrl}/api/socket?token=${token}`,
|
||||
extraHeaders: {
|
||||
origin: artCreatorUrl,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async function cdsLookup({
|
||||
e164s,
|
||||
acisAndAccessKeys = [],
|
||||
|
@ -4030,19 +4018,5 @@ export function initialize({
|
|||
useLibsignal,
|
||||
});
|
||||
}
|
||||
|
||||
//
|
||||
// Art
|
||||
//
|
||||
|
||||
async function getArtAuth(): Promise<ArtAuthType> {
|
||||
const response = await _ajax({
|
||||
call: 'getArtAuth',
|
||||
httpType: 'GET',
|
||||
responseType: 'json',
|
||||
});
|
||||
|
||||
return artAuthZod.parse(response);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,59 +0,0 @@
|
|||
// Copyright 2022 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { promisify } from 'util';
|
||||
|
||||
import { SignalService as Proto } from '../protobuf';
|
||||
import { calculateAgreement, generateKeyPair } from '../Curve';
|
||||
import { encryptAttachment, deriveSecrets } from '../Crypto';
|
||||
import * as Bytes from '../Bytes';
|
||||
|
||||
const PROVISIONING_INFO = 'Art Service Provisioning Message';
|
||||
|
||||
export type AuthorizeArtCreatorOptionsType = Readonly<{
|
||||
token: string;
|
||||
pubKeyBase64: string;
|
||||
}>;
|
||||
|
||||
export async function authorizeArtCreator({
|
||||
token,
|
||||
pubKeyBase64: theirPubKeyBase64,
|
||||
}: AuthorizeArtCreatorOptionsType): Promise<void> {
|
||||
const { server } = window.textsecure;
|
||||
if (!server) {
|
||||
throw new Error('Server not ready');
|
||||
}
|
||||
|
||||
const auth = await server.getArtAuth();
|
||||
|
||||
const ourKeys = generateKeyPair();
|
||||
const theirPubKey = Bytes.fromBase64(theirPubKeyBase64);
|
||||
|
||||
const secret = calculateAgreement(theirPubKey, ourKeys.privKey);
|
||||
const [aesKey, macKey] = deriveSecrets(
|
||||
secret,
|
||||
new Uint8Array(64),
|
||||
Bytes.fromString(PROVISIONING_INFO)
|
||||
);
|
||||
const keys = Bytes.concatenate([aesKey, macKey]);
|
||||
|
||||
const { ciphertext } = encryptAttachment({
|
||||
plaintext: Proto.ArtProvisioningMessage.encode({
|
||||
...auth,
|
||||
}).finish(),
|
||||
keys,
|
||||
});
|
||||
|
||||
const envelope = Proto.ArtProvisioningEnvelope.encode({
|
||||
publicKey: ourKeys.pubKey,
|
||||
ciphertext,
|
||||
}).finish();
|
||||
|
||||
const socket = await server.getArtProvisioningSocket(token);
|
||||
|
||||
try {
|
||||
await promisify(socket.sendBytes).call(socket, Buffer.from(envelope));
|
||||
} finally {
|
||||
socket.close(1000, 'goodbye');
|
||||
}
|
||||
}
|
|
@ -30,7 +30,6 @@ export type DirectoryConfigType = z.infer<typeof directoryConfigSchema>;
|
|||
export const rendererConfigSchema = z.object({
|
||||
appInstance: configOptionalStringSchema,
|
||||
appStartInitialSpellcheckSetting: z.boolean(),
|
||||
artCreatorUrl: configRequiredStringSchema,
|
||||
buildCreation: z.number(),
|
||||
buildExpiration: z.number(),
|
||||
cdnUrl0: configRequiredStringSchema,
|
||||
|
|
|
@ -16,7 +16,6 @@ import * as Errors from '../types/errors';
|
|||
import * as Stickers from '../types/Stickers';
|
||||
|
||||
import type { ConversationType } from '../state/ducks/conversations';
|
||||
import type { AuthorizeArtCreatorDataType } from '../state/ducks/globalModals';
|
||||
import { calling } from '../services/calling';
|
||||
import { resolveUsernameByLinkBase64 } from '../services/username';
|
||||
import { writeProfile } from '../services/writeProfile';
|
||||
|
@ -96,7 +95,6 @@ export type IPCEventsValuesType = {
|
|||
};
|
||||
|
||||
export type IPCEventsCallbacksType = {
|
||||
openArtCreator(): Promise<void>;
|
||||
getAvailableIODevices(): Promise<{
|
||||
availableCameras: Array<
|
||||
Pick<MediaDeviceInfo, 'deviceId' | 'groupId' | 'kind' | 'label'>
|
||||
|
@ -106,7 +104,6 @@ export type IPCEventsCallbacksType = {
|
|||
}>;
|
||||
addCustomColor: (customColor: CustomColorType) => void;
|
||||
addDarkOverlay: () => void;
|
||||
authorizeArtCreator: (data: AuthorizeArtCreatorDataType) => void;
|
||||
deleteAllData: () => Promise<void>;
|
||||
deleteAllMyStories: () => Promise<void>;
|
||||
editCustomColor: (colorId: string, customColor: CustomColorType) => void;
|
||||
|
@ -141,6 +138,10 @@ export type IPCEventsCallbacksType = {
|
|||
customColor?: { id: string; value: CustomColorType }
|
||||
) => void;
|
||||
getDefaultConversationColor: () => DefaultConversationColorType;
|
||||
uploadStickerPack: (
|
||||
manifest: Uint8Array,
|
||||
stickers: ReadonlyArray<Uint8Array>
|
||||
) => Promise<string>;
|
||||
};
|
||||
|
||||
type ValuesWithGetters = Omit<
|
||||
|
@ -239,15 +240,6 @@ export function createIPCEvents(
|
|||
};
|
||||
|
||||
return {
|
||||
openArtCreator: async () => {
|
||||
const auth = await window.textsecure.server?.getArtAuth();
|
||||
if (!auth) {
|
||||
return;
|
||||
}
|
||||
|
||||
window.openArtCreator(auth);
|
||||
},
|
||||
|
||||
getDeviceName: () => window.textsecure.storage.user.getDeviceName(),
|
||||
getPhoneNumber: () => {
|
||||
try {
|
||||
|
@ -530,14 +522,6 @@ export function createIPCEvents(
|
|||
});
|
||||
document.body.prepend(newOverlay);
|
||||
},
|
||||
authorizeArtCreator: (data: AuthorizeArtCreatorDataType) => {
|
||||
// We can get these events even if the user has never linked this instance.
|
||||
if (!Registration.everDone()) {
|
||||
log.warn('authorizeArtCreator: Not registered, returning early');
|
||||
return;
|
||||
}
|
||||
window.reduxActions.globalModals.showAuthorizeArtCreator(data);
|
||||
},
|
||||
removeDarkOverlay: () => {
|
||||
const elems = document.querySelectorAll('.dark-overlay');
|
||||
|
||||
|
@ -717,6 +701,16 @@ export function createIPCEvents(
|
|||
}
|
||||
},
|
||||
|
||||
uploadStickerPack: (
|
||||
manifest: Uint8Array,
|
||||
stickers: ReadonlyArray<Uint8Array>
|
||||
): Promise<string> => {
|
||||
strictAssert(window.textsecure.server, 'WebAPI must be available');
|
||||
return window.textsecure.server.putStickers(manifest, stickers, () =>
|
||||
ipcRenderer.send('art-creator:onUploadProgress')
|
||||
);
|
||||
},
|
||||
|
||||
...overrideEvents,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -439,38 +439,6 @@ export const artAddStickersRoute = _route('artAddStickers', {
|
|||
},
|
||||
});
|
||||
|
||||
/**
|
||||
* Art Service Authentication
|
||||
* @example
|
||||
* ```ts
|
||||
* artAuthRoute.toAppUrl({
|
||||
* token: "123",
|
||||
* pubKey: "abc",
|
||||
* })
|
||||
* // URL { "sgnl://art-auth?token=123&pub_key=abc" }
|
||||
*/
|
||||
export const artAuthRoute = _route('artAuth', {
|
||||
patterns: [_pattern('sgnl:', 'art-auth', '{/}?', { search: ':params' })],
|
||||
schema: z.object({
|
||||
token: paramSchema, // opaque
|
||||
pubKey: paramSchema, // base64url
|
||||
}),
|
||||
parse(result) {
|
||||
const params = new URLSearchParams(result.search.groups.params);
|
||||
return {
|
||||
token: params.get('token'),
|
||||
pubKey: params.get('pub_key'),
|
||||
};
|
||||
},
|
||||
toAppUrl(args) {
|
||||
const params = new URLSearchParams({
|
||||
token: args.token,
|
||||
pub_key: args.pubKey,
|
||||
});
|
||||
return new URL(`sgnl://art-auth?${params.toString()}`);
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
* Show a conversation
|
||||
* @example
|
||||
|
@ -594,7 +562,6 @@ const _allSignalRoutes = [
|
|||
captchaRoute,
|
||||
linkCallRoute,
|
||||
artAddStickersRoute,
|
||||
artAuthRoute,
|
||||
showConversationRoute,
|
||||
startCallLobbyRoute,
|
||||
showWindowRoute,
|
||||
|
|
|
@ -341,24 +341,6 @@ ipc.on('show-group-via-link', (_event, info) => {
|
|||
drop(window.Events.showGroupViaLink?.(info.value));
|
||||
});
|
||||
|
||||
ipc.on('open-art-creator', () => {
|
||||
drop(window.Events.openArtCreator());
|
||||
});
|
||||
|
||||
window.openArtCreator = ({
|
||||
username,
|
||||
password,
|
||||
}: {
|
||||
username: string;
|
||||
password: string;
|
||||
}) => {
|
||||
return ipc.invoke('open-art-creator', { username, password });
|
||||
};
|
||||
|
||||
ipc.on('authorize-art-creator', (_event, info) => {
|
||||
window.Events.authorizeArtCreator?.(info);
|
||||
});
|
||||
|
||||
ipc.on('start-call-lobby', (_event, { conversationId }) => {
|
||||
window.IPC.showWindow();
|
||||
window.reduxActions?.calling?.startCallingLobby({
|
||||
|
@ -458,3 +440,18 @@ ipc.on('show-release-notes', () => {
|
|||
showReleaseNotes();
|
||||
}
|
||||
});
|
||||
|
||||
ipc.on(
|
||||
'art-creator:uploadStickerPack',
|
||||
async (
|
||||
event,
|
||||
{
|
||||
manifest,
|
||||
stickers,
|
||||
}: { manifest: Uint8Array; stickers: ReadonlyArray<Uint8Array> }
|
||||
) => {
|
||||
const packId = await window.Events?.uploadStickerPack(manifest, stickers);
|
||||
|
||||
event.sender.send('art-creator:uploadStickerPack:done', packId);
|
||||
}
|
||||
);
|
||||
|
|
|
@ -27,7 +27,6 @@ window.WebAPI = window.textsecure.WebAPI.initialize({
|
|||
storageUrl: config.storageUrl,
|
||||
updatesUrl: config.updatesUrl,
|
||||
resourcesUrl: config.resourcesUrl,
|
||||
artCreatorUrl: config.artCreatorUrl,
|
||||
directoryConfig: config.directoryConfig,
|
||||
cdnUrlObject: {
|
||||
0: config.cdnUrl0,
|
||||
|
|
|
@ -3,8 +3,26 @@
|
|||
|
||||
import { contextBridge, ipcRenderer } from 'electron';
|
||||
|
||||
contextBridge.exposeInMainWorld('getCredentials', async () =>
|
||||
ipcRenderer.invoke('get-art-creator-auth')
|
||||
let onProgress: (() => void) | undefined;
|
||||
|
||||
ipcRenderer.on('art-creator:onUploadProgress', () => {
|
||||
onProgress?.();
|
||||
});
|
||||
|
||||
contextBridge.exposeInMainWorld(
|
||||
'uploadStickerPack',
|
||||
async (
|
||||
manifest: Uint8Array,
|
||||
stickers: Readonly<Uint8Array>,
|
||||
newOnProgress: (() => void) | undefined
|
||||
): Promise<string> => {
|
||||
onProgress = newOnProgress;
|
||||
|
||||
return ipcRenderer.invoke('art-creator:uploadStickerPack', {
|
||||
manifest,
|
||||
stickers,
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
contextBridge.exposeInMainWorld(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue