2020-11-04 20:49:08 +01:00
|
|
|
import {
|
|
|
|
Component,
|
|
|
|
OnInit,
|
|
|
|
} from '@angular/core';
|
|
|
|
|
|
|
|
import { ActivatedRoute } from '@angular/router';
|
|
|
|
|
2021-06-07 20:13:58 +02:00
|
|
|
import { ApiService } from 'jslib-common/abstractions/api.service';
|
|
|
|
import { CryptoService } from 'jslib-common/abstractions/crypto.service';
|
|
|
|
import { CryptoFunctionService } from 'jslib-common/abstractions/cryptoFunction.service';
|
|
|
|
import { I18nService } from 'jslib-common/abstractions/i18n.service';
|
|
|
|
import { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';
|
2020-11-04 20:49:08 +01:00
|
|
|
|
2021-06-07 20:13:58 +02:00
|
|
|
import { Utils } from 'jslib-common/misc/utils';
|
2020-11-04 20:49:08 +01:00
|
|
|
|
2021-06-07 20:13:58 +02:00
|
|
|
import { SendAccess } from 'jslib-common/models/domain/sendAccess';
|
|
|
|
import { SymmetricCryptoKey } from 'jslib-common/models/domain/symmetricCryptoKey';
|
2020-11-04 20:49:08 +01:00
|
|
|
|
2021-06-07 20:13:58 +02:00
|
|
|
import { SendAccessView } from 'jslib-common/models/view/sendAccessView';
|
2020-11-04 20:49:08 +01:00
|
|
|
|
2021-06-07 20:13:58 +02:00
|
|
|
import { SendType } from 'jslib-common/enums/sendType';
|
|
|
|
import { SendAccessRequest } from 'jslib-common/models/request/sendAccessRequest';
|
|
|
|
import { ErrorResponse } from 'jslib-common/models/response/errorResponse';
|
2020-11-04 20:49:08 +01:00
|
|
|
|
2021-06-07 20:13:58 +02:00
|
|
|
import { SendAccessResponse } from 'jslib-common/models/response/sendAccessResponse';
|
2020-11-04 20:49:08 +01:00
|
|
|
|
|
|
|
@Component({
|
|
|
|
selector: 'app-send-access',
|
|
|
|
templateUrl: 'access.component.html',
|
|
|
|
})
|
|
|
|
export class AccessComponent implements OnInit {
|
|
|
|
send: SendAccessView;
|
|
|
|
sendType = SendType;
|
|
|
|
downloading = false;
|
|
|
|
loading = true;
|
|
|
|
passwordRequired = false;
|
|
|
|
formPromise: Promise<SendAccessResponse>;
|
|
|
|
password: string;
|
|
|
|
showText = false;
|
2021-01-04 16:57:53 +01:00
|
|
|
unavailable = false;
|
|
|
|
error = false;
|
2021-04-05 22:26:04 +02:00
|
|
|
hideEmail = false;
|
2020-11-04 20:49:08 +01:00
|
|
|
|
|
|
|
private id: string;
|
|
|
|
private key: string;
|
|
|
|
private decKey: SymmetricCryptoKey;
|
2021-03-02 18:11:27 +01:00
|
|
|
private accessRequest: SendAccessRequest;
|
2020-11-04 20:49:08 +01:00
|
|
|
|
|
|
|
constructor(private i18nService: I18nService, private cryptoFunctionService: CryptoFunctionService,
|
|
|
|
private apiService: ApiService, private platformUtilsService: PlatformUtilsService,
|
|
|
|
private route: ActivatedRoute, private cryptoService: CryptoService) {
|
|
|
|
}
|
|
|
|
|
|
|
|
get sendText() {
|
|
|
|
if (this.send == null || this.send.text == null) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
return this.showText ? this.send.text.text : this.send.text.maskedText;
|
|
|
|
}
|
2021-02-25 23:25:53 +01:00
|
|
|
|
|
|
|
get expirationDate() {
|
|
|
|
if (this.send == null || this.send.expirationDate == null) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
return this.send.expirationDate;
|
|
|
|
}
|
|
|
|
|
|
|
|
get creatorIdentifier() {
|
|
|
|
if (this.send == null || this.send.creatorIdentifier == null) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
return this.send.creatorIdentifier;
|
|
|
|
}
|
2020-11-04 20:49:08 +01:00
|
|
|
|
|
|
|
ngOnInit() {
|
2021-02-03 18:41:33 +01:00
|
|
|
this.route.params.subscribe(async params => {
|
2020-11-04 20:49:08 +01:00
|
|
|
this.id = params.sendId;
|
|
|
|
this.key = params.key;
|
|
|
|
if (this.key == null || this.id == null) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
await this.load();
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
async download() {
|
|
|
|
if (this.send == null || this.decKey == null) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.downloading) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-03-02 18:11:27 +01:00
|
|
|
|
|
|
|
const downloadData = await this.apiService.getSendFileDownloadData(this.send, this.accessRequest);
|
|
|
|
|
|
|
|
if (Utils.isNullOrWhitespace(downloadData.url)) {
|
|
|
|
this.platformUtilsService.showToast('error', null, this.i18nService.t('missingSendFile'));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-11-04 20:49:08 +01:00
|
|
|
this.downloading = true;
|
2021-03-02 18:11:27 +01:00
|
|
|
const response = await fetch(new Request(downloadData.url, { cache: 'no-store' }));
|
2020-11-04 20:49:08 +01:00
|
|
|
if (response.status !== 200) {
|
|
|
|
this.platformUtilsService.showToast('error', null, this.i18nService.t('errorOccurred'));
|
|
|
|
this.downloading = false;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
try {
|
|
|
|
const buf = await response.arrayBuffer();
|
|
|
|
const decBuf = await this.cryptoService.decryptFromBytes(buf, this.decKey);
|
|
|
|
this.platformUtilsService.saveFile(window, decBuf, null, this.send.file.fileName);
|
|
|
|
} catch (e) {
|
|
|
|
this.platformUtilsService.showToast('error', null, this.i18nService.t('errorOccurred'));
|
|
|
|
}
|
|
|
|
|
|
|
|
this.downloading = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
copyText() {
|
|
|
|
this.platformUtilsService.copyToClipboard(this.send.text.text);
|
|
|
|
this.platformUtilsService.showToast('success', null,
|
|
|
|
this.i18nService.t('valueCopied', this.i18nService.t('sendTypeText')));
|
|
|
|
}
|
|
|
|
|
|
|
|
toggleText() {
|
|
|
|
this.showText = !this.showText;
|
|
|
|
}
|
|
|
|
|
2020-11-04 22:30:19 +01:00
|
|
|
async load() {
|
2021-01-04 16:57:53 +01:00
|
|
|
this.unavailable = false;
|
|
|
|
this.error = false;
|
2021-04-05 22:26:04 +02:00
|
|
|
this.hideEmail = false;
|
2020-11-04 20:49:08 +01:00
|
|
|
const keyArray = Utils.fromUrlB64ToArray(this.key);
|
2021-03-02 18:11:27 +01:00
|
|
|
this.accessRequest = new SendAccessRequest();
|
2020-11-04 20:49:08 +01:00
|
|
|
if (this.password != null) {
|
|
|
|
const passwordHash = await this.cryptoFunctionService.pbkdf2(this.password, keyArray, 'sha256', 100000);
|
2021-03-02 18:11:27 +01:00
|
|
|
this.accessRequest.password = Utils.fromBufferToB64(passwordHash);
|
2020-11-04 20:49:08 +01:00
|
|
|
}
|
|
|
|
try {
|
|
|
|
let sendResponse: SendAccessResponse = null;
|
|
|
|
if (this.loading) {
|
2021-03-02 18:11:27 +01:00
|
|
|
sendResponse = await this.apiService.postSendAccess(this.id, this.accessRequest);
|
2020-11-04 20:49:08 +01:00
|
|
|
} else {
|
2021-03-02 18:11:27 +01:00
|
|
|
this.formPromise = this.apiService.postSendAccess(this.id, this.accessRequest);
|
2020-11-04 20:49:08 +01:00
|
|
|
sendResponse = await this.formPromise;
|
|
|
|
}
|
|
|
|
this.passwordRequired = false;
|
|
|
|
const sendAccess = new SendAccess(sendResponse);
|
|
|
|
this.decKey = await this.cryptoService.makeSendKey(keyArray);
|
|
|
|
this.send = await sendAccess.decrypt(this.decKey);
|
|
|
|
this.showText = this.send.text != null ? !this.send.text.hidden : true;
|
|
|
|
} catch (e) {
|
|
|
|
if (e instanceof ErrorResponse) {
|
|
|
|
if (e.statusCode === 401) {
|
|
|
|
this.passwordRequired = true;
|
2021-01-04 16:57:53 +01:00
|
|
|
} else if (e.statusCode === 404) {
|
|
|
|
this.unavailable = true;
|
|
|
|
} else {
|
|
|
|
this.error = true;
|
2020-11-04 20:49:08 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
this.loading = false;
|
2021-04-05 22:26:04 +02:00
|
|
|
this.hideEmail = this.creatorIdentifier == null && !this.passwordRequired && !this.loading && !this.unavailable;
|
2020-11-04 20:49:08 +01:00
|
|
|
}
|
|
|
|
}
|