Procházet zdrojové kódy

Add main-page-config API: create controller, router, service, and schema; implement CORS with dynamic allowed origins

kai-zong před 8 měsíci
rodič
revize
8eabcf4e73

+ 48 - 9
config/middlewares.ts

@@ -1,4 +1,31 @@
-// middlewares.ts
+// config/middlewares.ts
+
+// Helper function to get allowed origins based on environment
+// Ensures required domains are always included
+const getAllowedOrigins = () => {
+  const allowedOrigins = [
+    'https://genomii.ai', // Your production frontend **REQUIRED**
+    // Add other domains if needed, e.g., staging environments
+  ];
+
+  // Optionally add localhost for development environments
+  if (process.env.NODE_ENV !== 'production') {
+    allowedOrigins.push('http://localhost:3000'); // Common React dev port
+    allowedOrigins.push('http://localhost:1337'); // Strapi default admin port
+  }
+  
+  // Include the Strapi server URL itself if necessary for admin panel or previews
+  if (process.env.URL) {
+     allowedOrigins.push(process.env.URL); // URL Strapi is running on (e.g., https://strapi.genomii.ai)
+  } else {
+    // Fallback if URL env var isn't set (adjust if needed)
+    allowedOrigins.push('https://strapi.genomii.ai'); 
+  }
+
+  return allowedOrigins;
+};
+
+
 export default [
   'strapi::logger',
   'strapi::errors',
@@ -8,31 +35,43 @@ export default [
       contentSecurityPolicy: {
         useDefaults: true,
         directives: {
-          'connect-src': ["'self'", 'https:'],
+          // Your existing CSP directives... make sure CLOUDFRONT_URL is properly set in your environment
+          'connect-src': ["'self'", 'https:'], 
           'img-src': [
             "'self'",
             'data:',
             'blob:',
             'https://market-assets.strapi.io',
-            'https://strapiblogcdkstack-media.s3.us-east-1.amazonaws.com', // Add your exact bucket URL
-            '*.s3.us-east-1.amazonaws.com', // Add this for broader coverage
-            `${process.env.CLOUDFRONT_URL || 'https://blog-media.genomii.ai'}` // Include CloudFront domain
+            `https://${process.env.AWS_BUCKET}.s3.${process.env.AWS_REGION}.amazonaws.com`, // Use env vars for bucket
+            '*.s3.amazonaws.com', // More general S3 pattern if needed
+            process.env.CLOUDFRONT_URL || 'https://blog-media.genomii.ai', // CloudFront domain
           ],
           'media-src': [
             "'self'",
             'data:',
             'blob:',
             'https://market-assets.strapi.io',
-            'https://strapiblogcdkstack-media.s3.us-east-1.amazonaws.com', // Add your exact bucket URL
-            '*.s3.us-east-1.amazonaws.com', // Add this for broader coverage
-            `${process.env.CLOUDFRONT_URL || 'https://blog-media.genomii.ai'}` // Include CloudFront domain
+            `https://${process.env.AWS_BUCKET}.s3.${process.env.AWS_REGION}.amazonaws.com`, // Use env vars for bucket
+            '*.s3.amazonaws.com', // More general S3 pattern if needed
+            process.env.CLOUDFRONT_URL || 'https://blog-media.genomii.ai', // CloudFront domain
           ],
           upgradeInsecureRequests: null,
         },
       },
     },
   },
-  'strapi::cors',
+  // == Replace 'strapi::cors' with this configuration object ==
+  {
+    name: 'strapi::cors',
+    config: {
+      enabled: true,
+      headers: '*', // Allow all headers, or specify ['Content-Type', 'Authorization', ...]
+      origin: getAllowedOrigins(), // Dynamically set allowed origins
+      methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS', 'HEAD'], // Common methods needed
+      credentials: false // Set to true if you need cookies/auth headers across origins
+    }
+  },
+  // ==========================================================
   'strapi::poweredBy',
   'strapi::query',
   'strapi::body',

+ 69 - 0
src/api/main-page-config/content-types/main-page-config/schema.json

@@ -0,0 +1,69 @@
+{
+  "kind": "singleType",
+  "collectionName": "main_page_configs",
+  "info": {
+    "singularName": "main-page-config",
+    "pluralName": "main-page-configs",
+    "displayName": "Main Page Config",
+    "description": ""
+  },
+  "options": {
+    "draftAndPublish": true
+  },
+  "attributes": {
+    "images": {
+      "type": "media",
+      "multiple": true,
+      "required": false,
+      "allowedTypes": [
+        "images",
+        "files",
+        "videos",
+        "audios"
+      ]
+    },
+    "vectors": {
+      "type": "media",
+      "multiple": true,
+      "required": false,
+      "allowedTypes": [
+        "images",
+        "files",
+        "videos",
+        "audios"
+      ]
+    },
+    "videos": {
+      "type": "media",
+      "multiple": true,
+      "required": false,
+      "allowedTypes": [
+        "images",
+        "files",
+        "videos",
+        "audios"
+      ]
+    },
+    "division2": {
+      "type": "json"
+    },
+    "division3": {
+      "type": "json"
+    },
+    "division4": {
+      "type": "json"
+    },
+    "division5": {
+      "type": "json"
+    },
+    "division6": {
+      "type": "json"
+    },
+    "division8": {
+      "type": "json"
+    },
+    "division9": {
+      "type": "json"
+    }
+  }
+}

+ 7 - 0
src/api/main-page-config/controllers/main-page-config.ts

@@ -0,0 +1,7 @@
+/**
+ * main-page-config controller
+ */
+
+import { factories } from '@strapi/strapi'
+
+export default factories.createCoreController('api::main-page-config.main-page-config');

+ 7 - 0
src/api/main-page-config/routes/main-page-config.ts

@@ -0,0 +1,7 @@
+/**
+ * main-page-config router
+ */
+
+import { factories } from '@strapi/strapi';
+
+export default factories.createCoreRouter('api::main-page-config.main-page-config');

+ 7 - 0
src/api/main-page-config/services/main-page-config.ts

@@ -0,0 +1,7 @@
+/**
+ * main-page-config service
+ */
+
+import { factories } from '@strapi/strapi';
+
+export default factories.createCoreService('api::main-page-config.main-page-config');

+ 49 - 0
types/generated/contentTypes.d.ts

@@ -575,6 +575,54 @@ export interface ApiGlobalGlobal extends Struct.SingleTypeSchema {
   };
 }
 
+export interface ApiMainPageConfigMainPageConfig
+  extends Struct.SingleTypeSchema {
+  collectionName: 'main_page_configs';
+  info: {
+    description: '';
+    displayName: 'Main Page Config';
+    pluralName: 'main-page-configs';
+    singularName: 'main-page-config';
+  };
+  options: {
+    draftAndPublish: true;
+  };
+  attributes: {
+    createdAt: Schema.Attribute.DateTime;
+    createdBy: Schema.Attribute.Relation<'oneToOne', 'admin::user'> &
+      Schema.Attribute.Private;
+    division2: Schema.Attribute.JSON;
+    division3: Schema.Attribute.JSON;
+    division4: Schema.Attribute.JSON;
+    division5: Schema.Attribute.JSON;
+    division6: Schema.Attribute.JSON;
+    division8: Schema.Attribute.JSON;
+    division9: Schema.Attribute.JSON;
+    images: Schema.Attribute.Media<
+      'images' | 'files' | 'videos' | 'audios',
+      true
+    >;
+    locale: Schema.Attribute.String & Schema.Attribute.Private;
+    localizations: Schema.Attribute.Relation<
+      'oneToMany',
+      'api::main-page-config.main-page-config'
+    > &
+      Schema.Attribute.Private;
+    publishedAt: Schema.Attribute.DateTime;
+    updatedAt: Schema.Attribute.DateTime;
+    updatedBy: Schema.Attribute.Relation<'oneToOne', 'admin::user'> &
+      Schema.Attribute.Private;
+    vectors: Schema.Attribute.Media<
+      'images' | 'files' | 'videos' | 'audios',
+      true
+    >;
+    videos: Schema.Attribute.Media<
+      'images' | 'files' | 'videos' | 'audios',
+      true
+    >;
+  };
+}
+
 export interface ApiTestTxtTestTxt extends Struct.SingleTypeSchema {
   collectionName: 'test_txts';
   info: {
@@ -1126,6 +1174,7 @@ declare module '@strapi/strapi' {
       'api::blog.blog': ApiBlogBlog;
       'api::category.category': ApiCategoryCategory;
       'api::global.global': ApiGlobalGlobal;
+      'api::main-page-config.main-page-config': ApiMainPageConfigMainPageConfig;
       'api::test-txt.test-txt': ApiTestTxtTestTxt;
       'plugin::content-releases.release': PluginContentReleasesRelease;
       'plugin::content-releases.release-action': PluginContentReleasesReleaseAction;