Browse Source

feat: don't unnecessarily prompt when installing libraries (#3329)

David Luzar 4 years ago
parent
commit
30ae4b8bf2

+ 2 - 1
src/components/App.tsx

@@ -609,7 +609,7 @@ class App extends React.Component<ExcalidrawProps, AppState> {
     this.onSceneUpdated();
   };
 
-  private importLibraryFromUrl = async (url: string) => {
+  private importLibraryFromUrl = async (url: string, token?: string | null) => {
     if (window.location.hash.includes(URL_HASH_KEYS.addLibrary)) {
       const hash = new URLSearchParams(window.location.hash.slice(1));
       hash.delete(URL_HASH_KEYS.addLibrary);
@@ -628,6 +628,7 @@ class App extends React.Component<ExcalidrawProps, AppState> {
         throw new Error();
       }
       if (
+        token === Library.csrfToken ||
         window.confirm(
           t("alerts.confirmAddLibrary", { numShapes: json.library.length }),
         )

+ 1 - 1
src/components/LayerUI.tsx

@@ -179,7 +179,7 @@ const LibraryMenuItems = ({
       <a
         href={`https://libraries.excalidraw.com?target=${
           window.name || "_blank"
-        }&referrer=${referrer}&useHash=true`}
+        }&referrer=${referrer}&useHash=true&token=${Library.csrfToken}`}
         target="_excalidraw_libraries"
       >
         {t("labels.libraries")}

+ 2 - 0
src/data/library.ts

@@ -4,9 +4,11 @@ import { restoreElements } from "./restore";
 import { STORAGE_KEYS } from "../constants";
 import { getNonDeletedElements } from "../element";
 import { NonDeleted, ExcalidrawElement } from "../element/types";
+import { nanoid } from "nanoid";
 
 export class Library {
   private static libraryCache: LibraryItems | null = null;
+  public static csrfToken = nanoid();
 
   static resetLibrary = () => {
     Library.libraryCache = null;

+ 3 - 4
src/excalidraw-app/index.tsx

@@ -221,16 +221,15 @@ function ExcalidrawWrapper() {
 
     const onHashChange = (event: HashChangeEvent) => {
       event.preventDefault();
-      const libraryUrl = new URLSearchParams(window.location.hash.slice(1)).get(
-        URL_HASH_KEYS.addLibrary,
-      );
+      const hash = new URLSearchParams(window.location.hash.slice(1));
+      const libraryUrl = hash.get(URL_HASH_KEYS.addLibrary);
       if (libraryUrl) {
         // If hash changed and it contains library url, import it and replace
         // the url to its previous state (important in case of collaboration
         // and similar).
         // Using history API won't trigger another hashchange.
         window.history.replaceState({}, "", event.oldURL);
-        excalidrawAPI.importLibrary(libraryUrl);
+        excalidrawAPI.importLibrary(libraryUrl, hash.get("token"));
       } else {
         initializeScene({ collabAPI }).then((scene) => {
           if (scene) {

+ 1 - 0
src/packages/excalidraw/CHANGELOG.md

@@ -18,6 +18,7 @@ Please add the latest change on the top under the correct section.
 
 ### Features
 
+- Support passing a CSRF token when importing libraries to prevent prompting before installation. The token is passed from [https://libraries.excalidraw.com](https://libraries.excalidraw.com/) using the `token` URL key [#3329](https://github.com/excalidraw/excalidraw/pull/3329).
 - #### BREAKING CHANGE
   Use `location.hash` when importing libraries to fix installation issues. This will require host apps to add a `hashchange` listener and call the newly exposed `excalidrawAPI.importLibrary(url)` API when applicable [#3320](https://github.com/excalidraw/excalidraw/pull/3320).
 - Append `location.pathname` to `libraryReturnUrl` default url [#3325](https://github.com/excalidraw/excalidraw/pull/3325).

+ 1 - 1
src/packages/excalidraw/README.md

@@ -473,7 +473,7 @@ You can pass a `ref` when you want to access some excalidraw APIs. We expose the
 | history | `{ clear: () => void }` | This is the history API. `history.clear()` will clear the history |
 | setScrollToContent | <pre> (<a href="https://github.com/excalidraw/excalidraw/blob/master/src/element/types.ts#L78">ExcalidrawElement[]</a>) => void </pre> | Scroll to the nearest element to center |
 | setCanvasOffsets | `() => void` | Updates the offsets for the Excalidraw component so that the coordinates are computed correctly (for example the cursor position). You should call this API when your app changes the dimensions/position of the Excalidraw container, such as when toggling a sidebar. You don't have to call this when the position is changed on page scroll (we handled that ourselves). |
-| importLibrary | `(url: string) => void` | Imports library from given URL. You should call this on `hashchange`, passing the `addLibrary` value if you detect it. |
+| importLibrary | `(url: string, token?: string) => void` | Imports library from given URL. You should call this on `hashchange`, passing the `addLibrary` value if you detect it. Optionally pass a CSRF `token` to skip prompting during installation (retrievable via `token` key from the url coming from [https://libraries.excalidraw.com](https://libraries.excalidraw.com/)). |
 
 #### `readyPromise`