aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgeireann <geireann.lindfield@gmail.com>2023-08-24 10:30:02 -0400
committergeireann <geireann.lindfield@gmail.com>2023-08-24 10:30:02 -0400
commitee95ae232a251d311d7055cecc9d3cfaded2d7d9 (patch)
tree5871e42f44db939b497ddb869897d9eb023bc0f4
parentf8c2d9d029f129eb595677b1e8a09ff1ebd5880c (diff)
parentd7aeb3aa85e7b66f503b61d72d459d69fb7788ea (diff)
Merge branch 'master' into sophie-ai-images
-rw-r--r--package.json2
-rw-r--r--src/client/views/DashboardView.tsx10
-rw-r--r--src/client/views/collections/CollectionDockingView.tsx2
-rw-r--r--src/client/views/collections/CollectionSubView.tsx6
-rw-r--r--src/client/views/nodes/ImageBox.tsx5
-rw-r--r--src/client/views/nodes/WebBoxRenderer.js6
-rw-r--r--src/server/ApiManagers/AzureManager.ts19
-rw-r--r--src/server/DashUploadUtils.ts17
8 files changed, 48 insertions, 19 deletions
diff --git a/package.json b/package.json
index 72f29ecf3..a1e7f858a 100644
--- a/package.json
+++ b/package.json
@@ -14,7 +14,7 @@
"start-release-debug": "cross-env RELEASE=true USE_AZURE=true NODE_OPTIONS=--max_old_space_size=4096 ts-node-dev --inspect -- src/server/index.ts",
"start": "cross-env NODE_OPTIONS=--max_old_space_size=4096 ts-node-dev --debug --transpile-only -- src/server/index.ts",
"oldstart": "cross-env NODE_OPTIONS=--max_old_space_size=4096 ts-node-dev --debug -- src/server/index.ts",
- "debug": "cross-env USE_AZURE=false NODE_OPTIONS=--max_old_space_size=8192 ts-node-dev --transpile-only --inspect -- src/server/index.ts",
+ "debug": "cross-env USE_AZURE=true NODE_OPTIONS=--max_old_space_size=8192 ts-node-dev --transpile-only --inspect -- src/server/index.ts",
"monitor": "cross-env MONITORED=true NODE_OPTIONS=--max_old_space_size=4096 ts-node src/server/index.ts",
"build": "cross-env NODE_OPTIONS=--max_old_space_size=8192 webpack --env production",
"test": "mocha -r ts-node/register test/**/*.ts",
diff --git a/src/client/views/DashboardView.tsx b/src/client/views/DashboardView.tsx
index 3e4827c83..231a2d5fb 100644
--- a/src/client/views/DashboardView.tsx
+++ b/src/client/views/DashboardView.tsx
@@ -47,12 +47,12 @@ export class DashboardView extends React.Component {
@action abortCreateNewDashboard = () => {
this.newDashboardName = undefined;
};
- @action setNewDashboardName(name: string) {
+ @action setNewDashboardName = (name: string) => {
this.newDashboardName = name;
- }
- @action setNewDashboardColor(color: string) {
+ };
+ @action setNewDashboardColor = (color: string) => {
this.newDashboardColor = color;
- }
+ };
@action
selectDashboardGroup = (group: DashboardGroup) => {
@@ -176,7 +176,7 @@ export class DashboardView extends React.Component {
</div>
<div className="all-dashboards">
{this.getDashboards(this.selectedDashboardGroup).map(dashboard => {
- const href = ImageCast(dashboard.thumb)?.url.href;
+ const href = ImageCast(dashboard.thumb)?.url?.href;
const shared = Object.keys(dashboard[DocAcl])
.filter(key => key !== `acl-${Doc.CurrentUserEmailNormalized}` && !['acl-Me', 'acl-Guest'].includes(key))
.some(key => dashboard[DocAcl][key] !== AclPrivate);
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index 95f88f14e..e15d57306 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -551,7 +551,7 @@ export class CollectionDockingView extends CollectionSubView() {
};
render() {
- const href = ImageCast(this.rootDoc.thumb)?.url.href;
+ const href = ImageCast(this.rootDoc.thumb)?.url?.href;
return this.props.renderDepth > -1 ? (
<div>
{href ? (
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index c189ef126..eb4685834 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -298,7 +298,11 @@ export function CollectionSubView<X>(moreProps?: X) {
let source = split;
if (split.startsWith('data:image') && split.includes('base64')) {
const [{ accessPaths }] = await Networking.PostToServer('/uploadRemoteImage', { sources: [split] });
- source = Utils.prepend(accessPaths.agnostic.client);
+ if (accessPaths.agnostic.client.indexOf("dashblobstore") === -1) {
+ source = Utils.prepend(accessPaths.agnostic.client);
+ } else {
+ source = accessPaths.agnostic.client;
+ }
}
if (source.startsWith('http')) {
const doc = Docs.Create.ImageDocument(source, { ...options, _width: 300 });
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index d62bbc3dc..c4b3f79a7 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -298,10 +298,11 @@ export class ImageBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
@computed private get url() {
const data = Cast(this.dataDoc[this.fieldKey], ImageField);
- return data ? data.url.href : undefined;
+ return data ? data.url?.href : undefined;
}
choosePath(url: URL) {
+ if (!url?.href) return "";
const lower = url.href.toLowerCase();
if (url.protocol === 'data') return url.href;
if (url.href.indexOf(window.location.origin) === -1 && url.href.indexOf('dashblobstore') === -1) return Utils.CorsProxy(url.href);
@@ -329,7 +330,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
if (!(data instanceof ImageField)) {
return null;
}
- const primary = data.url.href;
+ const primary = data.url?.href;
if (primary.includes(window.location.origin)) {
return null;
}
diff --git a/src/client/views/nodes/WebBoxRenderer.js b/src/client/views/nodes/WebBoxRenderer.js
index eb8064780..425ef3e54 100644
--- a/src/client/views/nodes/WebBoxRenderer.js
+++ b/src/client/views/nodes/WebBoxRenderer.js
@@ -42,21 +42,21 @@ var ForeignHtmlRenderer = function (styleSheets) {
url = CorsProxy(new URL(webUrl).origin + inurl);
} else if (!inurl.startsWith('http') && !inurl.startsWith('//')) {
url = CorsProxy(webUrl + '/' + inurl);
- } else if (inurl.startsWith('https')) {
+ } else if (inurl.startsWith('https') && !inurl.startsWith(window.location.origin)) {
url = CorsProxy(inurl);
}
xhr.open('GET', url);
xhr.responseType = 'blob';
xhr.onreadystatechange = async function () {
- if (xhr.readyState === 4 && xhr.status === 200) {
+ if (xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) {
const resBase64 = await binaryStringToBase64(xhr.response);
resolve({
resourceUrl: inurl,
resourceBase64: resBase64,
});
- } else if (xhr.readyState === 4) {
+ } else if (xhr.readyState === XMLHttpRequest.DONE) {
console.log("COULDN'T FIND: " + (inurl.startsWith('/') ? webUrl + inurl : inurl));
resolve({
resourceUrl: '',
diff --git a/src/server/ApiManagers/AzureManager.ts b/src/server/ApiManagers/AzureManager.ts
index 12bb98ad0..2d0ab3aa6 100644
--- a/src/server/ApiManagers/AzureManager.ts
+++ b/src/server/ApiManagers/AzureManager.ts
@@ -1,8 +1,18 @@
import { ContainerClient, BlobServiceClient } from "@azure/storage-blob";
import * as fs from "fs";
import { Readable, Stream } from "stream";
+import * as path from "path";
const AZURE_STORAGE_CONNECTION_STRING = process.env.AZURE_STORAGE_CONNECTION_STRING;
+const extToType: { [suffix: string]: string } = {
+ ".jpeg" : "image/jpeg",
+ ".jpg" : "image/jpeg",
+ ".png" : "image/png",
+ ".svg" : "image/svg+xml",
+ ".webp" : "image/webp",
+ ".gif" : "image/gif"
+}
+
export class AzureManager {
private _containerClient: ContainerClient;
private _blobServiceClient: BlobServiceClient;
@@ -10,6 +20,7 @@ export class AzureManager {
public static CONTAINER_NAME = "dashmedia";
public static STORAGE_ACCOUNT_NAME = "dashblobstore";
+ public static BASE_STRING = `https://${AzureManager.STORAGE_ACCOUNT_NAME}.blob.core.windows.net/${AzureManager.CONTAINER_NAME}`;
constructor() {
if (!AZURE_STORAGE_CONNECTION_STRING) {
@@ -38,6 +49,14 @@ export class AzureManager {
return blockBlobClient.uploadStream(stream, undefined, undefined, blobOptions);
}
+ public static UploadBase64ImageBlob(filename: string, data: string, filetype?: string) {
+ const confirmedFiletype = filetype ? filetype : extToType[path.extname(filename)];
+ const buffer = Buffer.from(data, "base64");
+ const blockBlobClient = this.Instance.ContainerClient.getBlockBlobClient(filename);
+ const blobOptions = { blobHTTPHeaders: { blobContentType: confirmedFiletype } };
+ return blockBlobClient.upload(buffer, buffer.length, blobOptions);
+ }
+
public static UploadBlobStream(stream: Readable, filename: string, filetype: string) {
const blockBlobClient = this.Instance.ContainerClient.getBlockBlobClient(filename);
const blobOptions = { blobHTTPHeaders: { blobContentType: filetype }};
diff --git a/src/server/DashUploadUtils.ts b/src/server/DashUploadUtils.ts
index 117981a7c..e5e15ce99 100644
--- a/src/server/DashUploadUtils.ts
+++ b/src/server/DashUploadUtils.ts
@@ -383,13 +383,18 @@ export namespace DashUploadUtils {
if ((rawMatches = /^data:image\/([a-z]+);base64,(.*)/.exec(source)) !== null) {
const [ext, data] = rawMatches.slice(1, 3);
const resolved = (filename = `upload_${Utils.GenerateGuid()}.${ext}`);
- const error = await new Promise<Error | null>(resolve => {
- writeFile(serverPathToFile(Directory.images, resolved), data, 'base64', resolve);
- });
- if (error !== null) {
- return error;
+ if (usingAzure()) {
+ const response = await AzureManager.UploadBase64ImageBlob(resolved, data);
+ source = `${AzureManager.BASE_STRING}/${resolved}`;
+ } else {
+ const error = await new Promise<Error | null>(resolve => {
+ writeFile(serverPathToFile(Directory.images, resolved), data, 'base64', resolve);
+ });
+ if (error !== null) {
+ return error;
+ }
+ source = `${resolvedServerUrl}${clientPathToFile(Directory.images, resolved)}`;
}
- source = `${resolvedServerUrl}${clientPathToFile(Directory.images, resolved)}`;
}
let resolvedUrl: string;
/**