Просмотр исходного кода

Merge pull request #10 from hakumizuki/feat/connection-generate-transfer-key

feat: connection generate transfer key
atsuki-t 3 лет назад
Родитель
Сommit
9e0f3df520

+ 13 - 0
packages/app/public/static/locales/en_US/admin.json

@@ -1024,5 +1024,18 @@
     "ADMIN_SEARCH_CONNECTION": "Attempting to reconnect to Elasticsearch",
     "ADMIN_SEARCH_INDICES_NORMALIZE": "Normalize of Elasticsearch indexes",
     "ADMIN_SEARCH_INDICES_REBUILD": "Rebuild Elasticsearch indexes"
+  },
+  "g2g_data_transfer": {
+    "tab": "Data transfer",
+    "data_transfer": "Growi To Growi Data Transfer",
+    "transfer_data_to_another_growi": "Transfer data from this GROWI to another GROWI",
+    "transfer_data_to_this_growi": "Transfer data from another GROWI to this GROWI",
+    "advanced_options": "Advanced options",
+    "start_transfer": "Start transfer",
+    "publish_transfer_key": "Publish transfer key",
+    "transfer_key_limit": "Transfer keys are valid for 1 hour after issuance.",
+    "once_transfer_key_used": "Once the transfer key is used for transfer, it cannot be used for any other transfer.",
+    "transfer_to_growi_cloud": "If you wish to transfer to GROWI.cloud, please click here.",
+    "paste_transfer_key": "Paste transter key here"
   }
 }

+ 20 - 0
packages/app/src/client/services/g2g-transfer.ts

@@ -0,0 +1,20 @@
+import { useMemo, useState } from 'react';
+
+import { throttle } from 'throttle-debounce';
+
+import { apiv3Post } from '~/client/util/apiv3-client';
+
+// eslint-disable-next-line @typescript-eslint/ban-types
+export const useGenerateTransferKeyWithThrottle = (): {transferKey: string, generateTransferKeyWithThrottle: Function} => {
+  const [transferKey, setTransferKey] = useState('');
+
+  const generateTransferKeyWithThrottle = useMemo(() => {
+    return throttle(1000, async() => {
+      const response = await apiv3Post('/g2g-transfer/generate-key');
+      const { transferKey } = response.data;
+      setTransferKey(transferKey);
+    });
+  }, []);
+
+  return { transferKey, generateTransferKeyWithThrottle };
+};

+ 17 - 14
packages/app/src/components/Admin/G2GDataTransfer.tsx

@@ -3,6 +3,7 @@ import React, { useCallback, useEffect, useState } from 'react';
 import { useTranslation } from 'react-i18next';
 import * as toastr from 'toastr';
 
+import { useGenerateTransferKeyWithThrottle } from '~/client/services/g2g-transfer';
 import { apiv3Get } from '~/client/util/apiv3-client';
 import { useAdminSocket } from '~/stores/socket-io';
 
@@ -23,7 +24,6 @@ const G2GDataTransfer = (): JSX.Element => {
   const [isExporting, setExporting] = useState(false);
   // TODO: データのエクスポートが完了したことが分かるようにする
   const [isExported, setExported] = useState(false);
-  const [transferKey, setTransferKey] = useState('');
 
   const fetchData = useCallback(async() => {
     const [{ data: collectionsData }, { data: statusData }] = await Promise.all([
@@ -67,10 +67,11 @@ const G2GDataTransfer = (): JSX.Element => {
     }
   }, [socket]);
 
-  const publishTransferKey = () => {
-    // 移行キー発行の処理
-    setTransferKey('transferKey');
-  };
+  const { transferKey, generateTransferKeyWithThrottle } = useGenerateTransferKeyWithThrottle();
+
+  const onClickHandler = useCallback(() => {
+    generateTransferKeyWithThrottle();
+  }, [generateTransferKeyWithThrottle]);
 
   const transferData = () => {
     // データ移行の処理
@@ -86,28 +87,30 @@ const G2GDataTransfer = (): JSX.Element => {
 
   return (
     <div data-testid="admin-export-archive-data">
-      <h2 className="border-bottom">{t('g2g_data_transfer.transfer_data_to_another_growi')}</h2>
+      <h2 className="border-bottom">{t('admin:g2g_data_transfer.transfer_data_to_another_growi')}</h2>
 
       <button type="button" className="btn btn-outline-secondary mt-4" disabled={isExporting} onClick={() => setExportModalOpen(true)}>
-        {t('g2g_data_transfer.advanced_options')}
+        {t('admin:g2g_data_transfer.advanced_options')}
       </button>
 
       <form onSubmit={transferData}>
         <div className="form-group row mt-3">
           <div className="col-9">
-            <input className="form-control" type="text" placeholder={t('g2g_data_transfer.paste_transfer_key')} />
+            <input className="form-control" type="text" placeholder={t('admin:g2g_data_transfer.paste_transfer_key')} />
           </div>
           <div className="col-3">
-            <button type="submit" className="btn btn-primary w-100">{t('g2g_data_transfer.start_transfer')}</button>
+            <button type="submit" className="btn btn-primary w-100">{t('admin:g2g_data_transfer.start_transfer')}</button>
           </div>
         </div>
       </form>
 
-      <h2 className="border-bottom mt-5">{t('g2g_data_transfer.transfer_data_to_this_growi')}</h2>
+      <h2 className="border-bottom mt-5">{t('admin:g2g_data_transfer.transfer_data_to_this_growi')}</h2>
 
       <div className="form-group row mt-4">
         <div className="col-md-3">
-          <button type="button" className="btn btn-primary w-100" onClick={publishTransferKey}>{t('g2g_data_transfer.publish_transfer_key')}</button>
+          <button type="button" className="btn btn-primary w-100" onClick={onClickHandler}>
+            {t('admin:g2g_data_transfer.publish_transfer_key')}
+          </button>
         </div>
         <div className="col-md-9">
           <div className="input-group-prepend mx-1">
@@ -118,9 +121,9 @@ const G2GDataTransfer = (): JSX.Element => {
       </div>
 
       <div className="alert alert-warning mt-4">
-        <p className="mb-1">{t('g2g_data_transfer.transfer_key_limit')}</p>
-        <p className="mb-1">{t('g2g_data_transfer.once_transfer_key_used')}</p>
-        <p className="mb-0">{t('g2g_data_transfer.transfer_to_growi_cloud')}</p>
+        <p className="mb-1">{t('admin:g2g_data_transfer.transfer_key_limit')}</p>
+        <p className="mb-1">{t('admin:g2g_data_transfer.once_transfer_key_used')}</p>
+        <p className="mb-0">{t('admin:g2g_data_transfer.transfer_to_growi_cloud')}</p>
       </div>
 
       <SelectCollectionsModal

+ 10 - 7
packages/app/src/components/DataTransferForm.tsx

@@ -1,19 +1,20 @@
-import React, { useState } from 'react';
+import React, { useCallback } from 'react';
 
 
 import { useTranslation } from 'react-i18next';
 
+import { useGenerateTransferKeyWithThrottle } from '~/client/services/g2g-transfer';
+
 import CustomCopyToClipBoard from './Common/CustomCopyToClipBoard';
 
 const DataTransferForm = (): JSX.Element => {
   const { t } = useTranslation();
 
-  const [transferKey, setTransferKey] = useState('');
+  const { transferKey, generateTransferKeyWithThrottle } = useGenerateTransferKeyWithThrottle();
 
-  const publishTransferKey = () => {
-    // 移行キー発行の処理
-    setTransferKey('transferKey');
-  };
+  const onClickHandler = useCallback(() => {
+    generateTransferKeyWithThrottle();
+  }, [generateTransferKeyWithThrottle]);
 
   return (
     <div data-testid="installerForm" className="p-3">
@@ -23,7 +24,9 @@ const DataTransferForm = (): JSX.Element => {
 
       <div className="form-group row mt-3">
         <div className="col-md-12">
-          <button type="button" className="btn btn-primary w-100" onClick={publishTransferKey}>{t('g2g_data_transfer.publish_transfer_key')}</button>
+          <button type="button" className="btn btn-primary w-100" onClick={onClickHandler}>
+            {t('g2g_data_transfer.publish_transfer_key')}
+          </button>
         </div>
         <div className="col-md-12 mt-1">
           <div className="input-group-prepend">

+ 1 - 1
packages/app/src/server/service/g2g-transfer.ts

@@ -205,7 +205,7 @@ export class G2GTransferReceiverService implements Receiver {
     // Generate transfer key string
     let transferKeyString: string;
     try {
-      transferKeyString = TransferKey.generateKeyString(appSiteUrl, uuid);
+      transferKeyString = TransferKey.generateKeyString(uuid, appSiteUrl);
     }
     catch (err) {
       logger.error(err);

+ 5 - 5
packages/app/src/utils/vo/transfer-key.ts

@@ -27,8 +27,8 @@ export class TransferKey {
     if (splitted.length !== 2) {
       throw Error(generalErrorPhrase);
     }
-    const appUrlString = splitted[0];
-    const key = splitted[1];
+    const key = splitted[0];
+    const appUrlString = splitted[1];
 
     let appUrl: URL | null;
     try {
@@ -43,12 +43,12 @@ export class TransferKey {
 
   /**
    * Generates transfer key string (e.g. https://example.com:8080__grw_internal_tranferkey__key)
-   * @param {URL} appUrl GROWI app site url
    * @param {string} key Key generated by GROWI
+   * @param {URL} appUrl GROWI app site url
    * @returns {string} Transfer key string
    */
-  static generateKeyString(appUrl: URL, key: string): string {
-    return `${appUrl.origin}${TransferKey._internalSeperator}${key}`;
+  static generateKeyString(key: string, appUrl: URL): string {
+    return `${key}${TransferKey._internalSeperator}${appUrl.origin}`;
   }
 
 }