@nextsparkjs/plugin-social-media-publisher 0.1.0-beta.68 → 0.1.0-beta.72

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.env.example CHANGED
@@ -1,16 +1,17 @@
1
- # ============================================================================
2
- # SOCIAL MEDIA PUBLISHER PLUGIN - ENVIRONMENT VARIABLES
3
- # ============================================================================
1
+ # ============================================
2
+ # SOCIAL MEDIA PUBLISHER PLUGIN CONFIGURATION
3
+ # ============================================
4
4
  #
5
- # Copy this file to .env and fill in your actual values
5
+ # Copy this file to .env and configure your social media credentials
6
+ # This file is loaded automatically by the Social Media Publisher plugin
6
7
  #
7
- # ⚠️ NEVER commit .env to git - it contains secrets!
8
+ # Priority: Plugin .env > Root .env > Defaults
8
9
  #
9
- # ============================================================================
10
+ # ============================================
10
11
 
11
- # ============================================================================
12
- # FACEBOOK/META OAUTH (Required for Instagram Business & Facebook Pages)
13
- # ============================================================================
12
+ # ===========================
13
+ # Facebook/Meta OAuth
14
+ # ===========================
14
15
  # Get from: https://developers.facebook.com/apps/
15
16
  # App Dashboard → Settings → Basic → App ID & App Secret
16
17
  #
@@ -23,54 +24,53 @@
23
24
  # - instagram_basic
24
25
  # - instagram_content_publish
25
26
  # - instagram_manage_comments
26
- #
27
- # Redirect URI: [YOUR_APP_URL]/api/v1/plugin/social-media-publisher/social/connect/callback
28
- # Example: https://yourdomain.com/api/v1/plugin/social-media-publisher/social/connect/callback
29
27
 
30
- FACEBOOK_CLIENT_ID="your-facebook-app-id"
31
- FACEBOOK_CLIENT_SECRET="your-facebook-app-secret"
28
+ # Facebook App ID
29
+ FACEBOOK_CLIENT_ID=your-facebook-app-id
30
+
31
+ # Facebook App Secret
32
+ FACEBOOK_CLIENT_SECRET=your-facebook-app-secret
32
33
 
33
- # Alternative names (both are supported):
34
- # FACEBOOK_APP_ID="your-facebook-app-id"
35
- # FACEBOOK_APP_SECRET="your-facebook-app-secret"
34
+ # ===========================
35
+ # OAuth Token Encryption
36
+ # ===========================
37
+ # Required for secure storage of OAuth tokens
38
+ # Generate with: openssl rand -hex 32
39
+ # Or: node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
36
40
 
37
- # ============================================================================
38
- # CRON JOB AUTHENTICATION (Required for scheduled publishing)
39
- # ============================================================================
40
- # Secret key to authenticate cron job requests
41
+ OAUTH_ENCRYPTION_KEY=your-32-byte-hex-encryption-key
42
+
43
+ # ===========================
44
+ # Cron Job Authentication
45
+ # ===========================
46
+ # Secret key to authenticate scheduled publishing requests
41
47
  # Generate with: openssl rand -base64 32
42
48
  #
43
- # This is used by the scheduled publishing endpoint:
44
- # POST /api/v1/cron/publish-scheduled
49
+ # Used by: POST /api/v1/cron/publish-scheduled
45
50
  # Header: Authorization: Bearer <CRON_SECRET>
46
- #
47
- # Configure in your cron service (Vercel Cron, GitHub Actions, etc.)
48
51
 
49
- CRON_SECRET="your-cron-secret-key-here"
52
+ CRON_SECRET=your-cron-secret-key-here
50
53
 
51
- # ============================================================================
52
- # USAGE NOTES
53
- # ============================================================================
54
+ # ===========================
55
+ # Quick Setup Guide
56
+ # ===========================
54
57
  #
55
- # 1. Copy this file:
56
- # cp .env.example .env
57
- #
58
- # 2. Create Facebook App:
58
+ # 1. Create Facebook App:
59
59
  # - Go to https://developers.facebook.com/apps/
60
60
  # - Create new app → Type: Business
61
61
  # - Add Facebook Login & Instagram API products
62
- # - Configure OAuth Redirect URIs
63
- # - Copy App ID & App Secret to this file
64
62
  #
65
- # 3. Generate CRON_SECRET:
63
+ # 2. Configure OAuth Redirect URI:
64
+ # [YOUR_APP_URL]/api/v1/plugin/social-media-publisher/social/connect/callback
65
+ #
66
+ # 3. Generate encryption key:
67
+ # openssl rand -hex 32
68
+ #
69
+ # 4. Generate cron secret:
66
70
  # openssl rand -base64 32
67
71
  #
68
- # 4. Configure Vercel Cron (see vercel.json):
72
+ # 5. For Vercel Cron (see vercel.json):
69
73
  # - Add CRON_SECRET to Vercel Environment Variables
70
74
  # - Cron runs every 5 minutes by default
71
75
  #
72
- # 5. Test scheduled publishing:
73
- # curl -X POST http://localhost:5173/api/v1/cron/publish-scheduled \
74
- # -H "Authorization: Bearer YOUR_CRON_SECRET"
75
- #
76
- # ============================================================================
76
+ # ⚠️ NEVER commit .env to git - it contains secrets!
package/README.md CHANGED
@@ -251,6 +251,46 @@ async function publishToInstagram(account: any, imageUrl: string, caption: strin
251
251
 
252
252
  ## Environment Variables
253
253
 
254
+ ### ⭐ Plugin-Level Environment Configuration (Recommended)
255
+
256
+ The Social Media Publisher plugin supports **plugin-level `.env` files** that take priority over root environment variables.
257
+
258
+ #### Setup
259
+
260
+ 1. **Copy the example file:**
261
+ ```bash
262
+ cp contents/plugins/social-media-publisher/.env.example contents/plugins/social-media-publisher/.env
263
+ ```
264
+
265
+ 2. **Configure your credentials:**
266
+ ```env
267
+ # Facebook/Meta OAuth
268
+ FACEBOOK_CLIENT_ID="your-facebook-app-id"
269
+ FACEBOOK_CLIENT_SECRET="your-facebook-app-secret"
270
+
271
+ # Cron Job Authentication
272
+ CRON_SECRET="your-cron-secret-key-here"
273
+ ```
274
+
275
+ #### Priority System
276
+
277
+ The plugin environment loader uses this priority:
278
+
279
+ 1. **Plugin `.env`** (`contents/plugins/social-media-publisher/.env`) - Highest priority
280
+ 2. **Root `.env`** (`/.env`) - Fallback for variables not in plugin .env
281
+ 3. **Built-in defaults** - Lowest priority
282
+
283
+ #### Benefits
284
+
285
+ - ✅ **Isolation**: OAuth credentials isolated to the plugin
286
+ - ✅ **Security**: Sensitive keys scoped to specific plugins
287
+ - ✅ **Modularity**: Each plugin manages its own secrets
288
+ - ✅ **Flexibility**: Different configs per environment
289
+
290
+ ### Root Environment Variables (Alternative)
291
+
292
+ You can also configure credentials in the root `.env`:
293
+
254
294
  ```env
255
295
  # Facebook App Credentials (same as Better Auth)
256
296
  FACEBOOK_CLIENT_ID=your_app_id
@@ -0,0 +1,164 @@
1
+ /**
2
+ * Social Media Publisher Plugin Environment Configuration (Server-Only)
3
+ *
4
+ * Uses centralized plugin environment loader from core
5
+ * Provides type-safe access to OAuth and publishing configuration
6
+ */
7
+
8
+ import { getPluginEnv } from '@nextsparkjs/core/lib/plugins/env-loader'
9
+
10
+ interface SocialMediaPublisherEnvConfig {
11
+ // Facebook/Meta OAuth
12
+ FACEBOOK_CLIENT_ID?: string
13
+ FACEBOOK_CLIENT_SECRET?: string
14
+ FACEBOOK_APP_ID?: string // Alternative name
15
+ FACEBOOK_APP_SECRET?: string // Alternative name
16
+
17
+ // OAuth Encryption
18
+ OAUTH_ENCRYPTION_KEY?: string
19
+
20
+ // Cron Job Authentication
21
+ CRON_SECRET?: string
22
+
23
+ // App URL
24
+ NEXT_PUBLIC_APP_URL?: string
25
+ }
26
+
27
+ class PluginEnvironment {
28
+ private static instance: PluginEnvironment
29
+ private config: SocialMediaPublisherEnvConfig = {}
30
+ private loaded = false
31
+
32
+ private constructor() {
33
+ this.loadEnvironment()
34
+ }
35
+
36
+ public static getInstance(): PluginEnvironment {
37
+ if (!PluginEnvironment.instance) {
38
+ PluginEnvironment.instance = new PluginEnvironment()
39
+ }
40
+ return PluginEnvironment.instance
41
+ }
42
+
43
+ private loadEnvironment(forceReload: boolean = false): void {
44
+ if (this.loaded && !forceReload) return
45
+
46
+ try {
47
+ // Use centralized plugin env loader
48
+ const env = getPluginEnv('social-media-publisher')
49
+
50
+ this.config = {
51
+ // Facebook/Meta OAuth (support both naming conventions)
52
+ FACEBOOK_CLIENT_ID: env.FACEBOOK_CLIENT_ID || env.FACEBOOK_APP_ID,
53
+ FACEBOOK_CLIENT_SECRET: env.FACEBOOK_CLIENT_SECRET || env.FACEBOOK_APP_SECRET,
54
+ FACEBOOK_APP_ID: env.FACEBOOK_APP_ID || env.FACEBOOK_CLIENT_ID,
55
+ FACEBOOK_APP_SECRET: env.FACEBOOK_APP_SECRET || env.FACEBOOK_CLIENT_SECRET,
56
+
57
+ // OAuth Encryption
58
+ OAUTH_ENCRYPTION_KEY: env.OAUTH_ENCRYPTION_KEY,
59
+
60
+ // Cron Job Authentication
61
+ CRON_SECRET: env.CRON_SECRET,
62
+
63
+ // App URL
64
+ NEXT_PUBLIC_APP_URL: env.NEXT_PUBLIC_APP_URL,
65
+ }
66
+
67
+ this.logLoadedConfiguration()
68
+ this.loaded = true
69
+ } catch (error) {
70
+ console.error('[Social Media Publisher] Failed to load environment:', error)
71
+ this.loaded = true
72
+ }
73
+ }
74
+
75
+ private logLoadedConfiguration(): void {
76
+ if (process.env.NODE_ENV === 'development') {
77
+ console.log('[Social Media Publisher] Environment Configuration:')
78
+ console.log(' → Facebook/Meta OAuth:')
79
+ console.log(` - FACEBOOK_CLIENT_ID: ${this.config.FACEBOOK_CLIENT_ID ? '✓ set' : '✗ not set'}`)
80
+ console.log(` - FACEBOOK_CLIENT_SECRET: ${this.config.FACEBOOK_CLIENT_SECRET ? '✓ set' : '✗ not set'}`)
81
+ console.log(' → OAuth Encryption:')
82
+ console.log(` - OAUTH_ENCRYPTION_KEY: ${this.config.OAUTH_ENCRYPTION_KEY ? '✓ set' : '✗ not set'}`)
83
+ console.log(' → Cron Authentication:')
84
+ console.log(` - CRON_SECRET: ${this.config.CRON_SECRET ? '✓ set' : '✗ not set'}`)
85
+ console.log(' → App Configuration:')
86
+ console.log(` - NEXT_PUBLIC_APP_URL: ${this.config.NEXT_PUBLIC_APP_URL || 'not set'}`)
87
+ console.log()
88
+ }
89
+ }
90
+
91
+ public getConfig(): SocialMediaPublisherEnvConfig {
92
+ if (!this.loaded) {
93
+ this.loadEnvironment()
94
+ }
95
+ return this.config
96
+ }
97
+
98
+ // Helper methods
99
+ public getFacebookClientId(): string | undefined {
100
+ return this.getConfig().FACEBOOK_CLIENT_ID
101
+ }
102
+
103
+ public getFacebookClientSecret(): string | undefined {
104
+ return this.getConfig().FACEBOOK_CLIENT_SECRET
105
+ }
106
+
107
+ public getOAuthEncryptionKey(): string | undefined {
108
+ return this.getConfig().OAUTH_ENCRYPTION_KEY
109
+ }
110
+
111
+ public getCronSecret(): string | undefined {
112
+ return this.getConfig().CRON_SECRET
113
+ }
114
+
115
+ public getAppUrl(): string | undefined {
116
+ return this.getConfig().NEXT_PUBLIC_APP_URL
117
+ }
118
+
119
+ public hasFacebookCredentials(): boolean {
120
+ const config = this.getConfig()
121
+ return !!(config.FACEBOOK_CLIENT_ID && config.FACEBOOK_CLIENT_SECRET)
122
+ }
123
+
124
+ public hasOAuthEncryption(): boolean {
125
+ return !!this.getConfig().OAUTH_ENCRYPTION_KEY
126
+ }
127
+
128
+ public validateEnvironment(): { valid: boolean; errors: string[] } {
129
+ const errors: string[] = []
130
+ const config = this.getConfig()
131
+
132
+ if (!config.FACEBOOK_CLIENT_ID) {
133
+ errors.push('FACEBOOK_CLIENT_ID is required for OAuth')
134
+ }
135
+ if (!config.FACEBOOK_CLIENT_SECRET) {
136
+ errors.push('FACEBOOK_CLIENT_SECRET is required for OAuth')
137
+ }
138
+ if (!config.OAUTH_ENCRYPTION_KEY) {
139
+ errors.push('OAUTH_ENCRYPTION_KEY is required for token encryption')
140
+ }
141
+
142
+ return {
143
+ valid: errors.length === 0,
144
+ errors,
145
+ }
146
+ }
147
+
148
+ public reload(): void {
149
+ this.loaded = false
150
+ this.loadEnvironment(true)
151
+ }
152
+ }
153
+
154
+ export const pluginEnv = PluginEnvironment.getInstance()
155
+
156
+ // Convenience exports
157
+ export const getFacebookClientId = () => pluginEnv.getFacebookClientId()
158
+ export const getFacebookClientSecret = () => pluginEnv.getFacebookClientSecret()
159
+ export const getOAuthEncryptionKey = () => pluginEnv.getOAuthEncryptionKey()
160
+ export const getCronSecret = () => pluginEnv.getCronSecret()
161
+ export const getAppUrl = () => pluginEnv.getAppUrl()
162
+ export const hasFacebookCredentials = () => pluginEnv.hasFacebookCredentials()
163
+ export const hasOAuthEncryption = () => pluginEnv.hasOAuthEncryption()
164
+ export const validateEnvironment = () => pluginEnv.validateEnvironment()
package/package.json CHANGED
@@ -1,19 +1,19 @@
1
1
  {
2
2
  "name": "@nextsparkjs/plugin-social-media-publisher",
3
- "version": "0.1.0-beta.68",
3
+ "version": "0.1.0-beta.72",
4
4
  "private": false,
5
5
  "main": "./plugin.config.ts",
6
6
  "requiredPlugins": [],
7
7
  "dependencies": {},
8
8
  "peerDependencies": {
9
+ "@nextsparkjs/core": "workspace:*",
9
10
  "next": "^15.0.0",
10
11
  "react": "^19.0.0",
11
12
  "react-dom": "^19.0.0",
12
- "zod": "^4.0.0",
13
- "@nextsparkjs/core": "0.1.0-beta.68"
13
+ "zod": "^4.0.0"
14
14
  },
15
15
  "nextspark": {
16
16
  "type": "plugin",
17
17
  "name": "social-media-publisher"
18
18
  }
19
- }
19
+ }
package/LICENSE DELETED
@@ -1,21 +0,0 @@
1
- MIT License
2
-
3
- Copyright (c) 2025 NextSpark
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.