Handle ws connexion status code & fix token validation

This commit is contained in:
Convly 2023-03-14 12:43:15 +01:00
parent d85c05d246
commit d8614487de
6 changed files with 67 additions and 23 deletions

View File

@ -36,7 +36,7 @@ const FormTransferTokenContainer = ({
value: 'push-pull',
label: {
id: 'Settings.transferTokens.types.push-pull',
defaultMessage: 'Push & pull',
defaultMessage: 'Full Access',
},
},
];

View File

@ -24,6 +24,10 @@ module.exports = {
DAYS_30: 30 * DAY_IN_MS,
DAYS_90: 90 * DAY_IN_MS,
},
TRANSFER_TOKEN_TYPE: {
PUSH: 'push',
PULL: 'pull',
},
TRANSFER_TOKEN_LIFESPANS: {
UNLIMITED: null,
DAYS_7: 7 * DAY_IN_MS,

View File

@ -8,7 +8,11 @@ const transferTokenCreationSchema = yup
.shape({
name: yup.string().min(1).required(),
description: yup.string().optional(),
permissions: yup.array().of(yup.string()).nullable(),
permissions: yup
.array()
.min(1)
.of(yup.string().oneOf(Object.values(constants.TRANSFER_TOKEN_TYPE)))
.required(),
lifespan: yup
.number()
.min(1)
@ -23,7 +27,11 @@ const transferTokenUpdateSchema = yup
.shape({
name: yup.string().min(1).notNull(),
description: yup.string().nullable(),
permissions: yup.array().of(yup.string()).nullable(),
permissions: yup
.array()
.min(1)
.of(yup.string().oneOf(Object.values(constants.TRANSFER_TOKEN_TYPE)))
.required(),
})
.noUnknown()
.strict();

View File

@ -1,6 +1,6 @@
import { PassThrough, Readable, Transform } from 'stream';
import { PassThrough, Readable } from 'stream';
import { WebSocket } from 'ws';
import { once } from 'lodash/fp';
import type {
IAsset,
IMetadata,
@ -11,7 +11,11 @@ import type {
TransferStage,
} from '../../../../types';
import { client, server } from '../../../../types/remote/protocol';
import { ProviderTransferError, ProviderValidationError } from '../../../errors/providers';
import {
ProviderInitializationError,
ProviderTransferError,
ProviderValidationError,
} from '../../../errors/providers';
import { TRANSFER_PATH } from '../../remote/constants';
import { ILocalStrapiSourceProviderOptions } from '../local-source';
import { createDispatcher } from '../utils';
@ -168,6 +172,37 @@ class RemoteStrapiSourceProvider implements ISourceProvider {
async initTransfer(): Promise<string> {
return new Promise<string>((resolve, reject) => {
this.ws
?.on('unexpected-response', (_req, res) => {
if (res.statusCode === 401) {
return reject(
new ProviderInitializationError(
'Failed to initialize the connexion: Authentication Error'
)
);
}
if (res.statusCode === 403) {
return reject(
new ProviderInitializationError(
'Failed to initialize the connexion: Authorization Error'
)
);
}
if (res.statusCode === 404) {
return reject(
new ProviderInitializationError(
'Failed to initialize the connexion: Data transfer is not enabled on the remote host'
)
);
}
return reject(
new ProviderInitializationError(
`Failed to initialize the connexion: Unexpected server response ${res.statusCode}`
)
);
})
?.once('open', async () => {
const query = this.dispatcher?.dispatchCommand({
command: 'init',
@ -187,7 +222,7 @@ class RemoteStrapiSourceProvider implements ISourceProvider {
});
}
async bootstrap?(): Promise<void> {
async bootstrap(): Promise<void> {
const { url, auth } = this.options;
let ws: WebSocket;
this.assertValidProtocol(url);
@ -245,10 +280,6 @@ class RemoteStrapiSourceProvider implements ISourceProvider {
return schemas;
}
#startStepOnce(stage: client.TransferPullStep) {
return once(() => this.#startStep(stage));
}
async #startStep<T extends client.TransferPullStep>(step: T) {
try {
return await this.dispatcher?.dispatchTransferStep({ action: 'start', step });

View File

@ -1,4 +1,4 @@
import { Readable, Transform } from 'stream';
import { Readable } from 'stream';
import { randomUUID } from 'crypto';
import { Handler } from './abstract';
@ -62,6 +62,10 @@ export const createPullController = handlerControllerFactory<Partial<PullHandler
async onMessage(this: PullHandler, raw) {
const msg = JSON.parse(raw.toString());
if (!isDataTransferMessage(msg)) {
return;
}
if (!msg.uuid) {
await this.respond(undefined, new Error('Missing uuid in message'));
}
@ -70,12 +74,17 @@ export const createPullController = handlerControllerFactory<Partial<PullHandler
// Regular command message (init, end, status)
if (type === 'command') {
const { command, params } = msg;
const { command } = msg;
await this.executeAndRespond(uuid, () => {
this.assertValidTransferCommand(command);
return this[command](params);
// The status command don't have params
if (command === 'status') {
return this.status();
}
return this[command](msg.params);
});
}

View File

@ -143,15 +143,7 @@ export const handlerControllerFactory =
},
send(message, cb) {
let payload;
try {
payload = JSON.stringify(message);
} catch {
payload = message;
}
ws.send(payload as string, cb);
ws.send(message, cb);
},
confirm(message) {