@knowcode/doc-builder 1.7.5 → 1.7.6
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/CHANGELOG.md +32 -0
- package/README.md +24 -1
- package/add-user-clive.sql +35 -0
- package/add-user-lindsay-fixed.sql +85 -0
- package/add-user-lindsay.sql +68 -0
- package/add-user-pmorgan.sql +35 -0
- package/add-user-robbie.sql +35 -0
- package/add-wru-users.sql +105 -0
- package/cli.js +9 -1
- package/html/README.html +3 -3
- package/html/documentation-index.html +3 -3
- package/html/guides/authentication-default-change.html +3 -3
- package/html/guides/authentication-guide.html +3 -3
- package/html/guides/cache-control-anti-pattern.html +3 -3
- package/html/guides/claude-workflow-guide.html +3 -3
- package/html/guides/documentation-standards.html +3 -3
- package/html/guides/next-steps-walkthrough.html +3 -3
- package/html/guides/phosphor-icons-guide.html +3 -3
- package/html/guides/public-site-deployment.html +3 -3
- package/html/guides/search-engine-verification-guide.html +3 -3
- package/html/guides/seo-guide.html +3 -3
- package/html/guides/seo-optimization-guide.html +3 -3
- package/html/guides/supabase-auth-implementation-plan.html +3 -3
- package/html/guides/supabase-auth-integration-plan.html +3 -3
- package/html/guides/supabase-auth-setup-guide.html +3 -3
- package/html/guides/troubleshooting-guide.html +3 -3
- package/html/guides/vercel-deployment-auth-setup.html +3 -3
- package/html/guides/windows-setup-guide.html +3 -3
- package/html/index.html +3 -3
- package/html/launch/README.html +3 -3
- package/html/launch/bubble-plugin-specification.html +3 -3
- package/html/launch/go-to-market-strategy.html +3 -3
- package/html/launch/launch-announcements.html +3 -3
- package/html/sitemap.xml +29 -29
- package/html/vercel-cli-setup-guide.html +3 -3
- package/html/vercel-first-time-setup-guide.html +3 -3
- package/lib/config.js +22 -3
- package/lib/core-builder.js +91 -1
- package/manage-users.sql +191 -0
- package/package.json +1 -1
- package/view-all-users.sql +40 -0
- package/wru-auth-config.js +17 -0
- package/assets/js/auth.js +0 -67
package/lib/config.js
CHANGED
|
@@ -30,7 +30,8 @@ const defaultConfig = {
|
|
|
30
30
|
phosphorSize: '1.2em', // Relative to text size
|
|
31
31
|
normalizeTitle: true, // Auto-normalize all-caps titles to title case
|
|
32
32
|
showPdfDownload: true, // Show PDF download icon in header
|
|
33
|
-
menuDefaultOpen: true
|
|
33
|
+
menuDefaultOpen: true, // Menu/sidebar open by default
|
|
34
|
+
attachments: true // Copy attachments (Excel, PDF, etc.) to output
|
|
34
35
|
},
|
|
35
36
|
|
|
36
37
|
// Authentication - Supabase only (basic auth removed for security)
|
|
@@ -78,7 +79,21 @@ const defaultConfig = {
|
|
|
78
79
|
generateSitemap: true,
|
|
79
80
|
generateRobotsTxt: true,
|
|
80
81
|
customMetaTags: []
|
|
81
|
-
}
|
|
82
|
+
},
|
|
83
|
+
|
|
84
|
+
// Attachment file types to copy
|
|
85
|
+
attachmentTypes: [
|
|
86
|
+
// Documents
|
|
87
|
+
'.pdf', '.doc', '.docx', '.xls', '.xlsx', '.csv', '.ppt', '.pptx', '.txt', '.rtf',
|
|
88
|
+
// Archives
|
|
89
|
+
'.zip', '.tar', '.gz', '.7z', '.rar',
|
|
90
|
+
// Images
|
|
91
|
+
'.png', '.jpg', '.jpeg', '.gif', '.svg', '.webp', '.ico', '.bmp',
|
|
92
|
+
// Data files
|
|
93
|
+
'.json', '.xml', '.yaml', '.yml', '.toml',
|
|
94
|
+
// Other
|
|
95
|
+
'.mp4', '.mp3', '.wav', '.avi', '.mov'
|
|
96
|
+
]
|
|
82
97
|
};
|
|
83
98
|
|
|
84
99
|
/**
|
|
@@ -102,7 +117,8 @@ const notionInspiredPreset = {
|
|
|
102
117
|
phosphorSize: '1.2em',
|
|
103
118
|
normalizeTitle: true,
|
|
104
119
|
showPdfDownload: true,
|
|
105
|
-
menuDefaultOpen: true
|
|
120
|
+
menuDefaultOpen: true,
|
|
121
|
+
attachments: true
|
|
106
122
|
},
|
|
107
123
|
|
|
108
124
|
auth: {
|
|
@@ -261,6 +277,9 @@ async function loadConfig(configPath, options = {}) {
|
|
|
261
277
|
if (options.menuClosed === true) {
|
|
262
278
|
config.features.menuDefaultOpen = false;
|
|
263
279
|
}
|
|
280
|
+
if (options.attachments === false) {
|
|
281
|
+
config.features.attachments = false;
|
|
282
|
+
}
|
|
264
283
|
|
|
265
284
|
// Legacy mode - auto-detect structure
|
|
266
285
|
if (options.legacy) {
|
package/lib/core-builder.js
CHANGED
|
@@ -753,6 +753,62 @@ async function getAllMarkdownFiles(dir, baseDir = dir) {
|
|
|
753
753
|
return files;
|
|
754
754
|
}
|
|
755
755
|
|
|
756
|
+
// Get all attachment files
|
|
757
|
+
async function getAllAttachmentFiles(dir, baseDir = dir, attachmentTypes) {
|
|
758
|
+
const files = [];
|
|
759
|
+
const items = await fs.readdir(dir);
|
|
760
|
+
|
|
761
|
+
for (const item of items) {
|
|
762
|
+
const fullPath = path.join(dir, item);
|
|
763
|
+
const stat = await fs.stat(fullPath);
|
|
764
|
+
|
|
765
|
+
if (stat.isDirectory() && !item.startsWith('.')) {
|
|
766
|
+
// Recursively scan subdirectories
|
|
767
|
+
const subFiles = await getAllAttachmentFiles(fullPath, baseDir, attachmentTypes);
|
|
768
|
+
files.push(...subFiles);
|
|
769
|
+
} else {
|
|
770
|
+
// Check if file is an attachment type
|
|
771
|
+
const ext = path.extname(item).toLowerCase();
|
|
772
|
+
if (attachmentTypes.includes(ext) && !item.startsWith('.')) {
|
|
773
|
+
const relativePath = path.relative(baseDir, fullPath);
|
|
774
|
+
files.push({
|
|
775
|
+
path: fullPath,
|
|
776
|
+
relativePath,
|
|
777
|
+
size: stat.size
|
|
778
|
+
});
|
|
779
|
+
}
|
|
780
|
+
}
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
return files;
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
// Copy attachment files to output directory
|
|
787
|
+
async function copyAttachmentFiles(attachmentFiles, docsDir, outputDir) {
|
|
788
|
+
let totalSize = 0;
|
|
789
|
+
let copiedCount = 0;
|
|
790
|
+
|
|
791
|
+
for (const file of attachmentFiles) {
|
|
792
|
+
try {
|
|
793
|
+
const outputPath = path.join(outputDir, file.relativePath);
|
|
794
|
+
const outputDirPath = path.dirname(outputPath);
|
|
795
|
+
|
|
796
|
+
// Create directory if it doesn't exist
|
|
797
|
+
await fs.ensureDir(outputDirPath);
|
|
798
|
+
|
|
799
|
+
// Copy the file
|
|
800
|
+
await fs.copy(file.path, outputPath, { overwrite: true });
|
|
801
|
+
|
|
802
|
+
totalSize += file.size;
|
|
803
|
+
copiedCount++;
|
|
804
|
+
} catch (error) {
|
|
805
|
+
console.warn(chalk.yellow(`Warning: Could not copy ${file.relativePath}: ${error.message}`));
|
|
806
|
+
}
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
return { copiedCount, totalSize };
|
|
810
|
+
}
|
|
811
|
+
|
|
756
812
|
// Main build function
|
|
757
813
|
async function buildDocumentation(config) {
|
|
758
814
|
const docsDir = path.join(process.cwd(), config.docsDir);
|
|
@@ -946,7 +1002,41 @@ async function buildDocumentation(config) {
|
|
|
946
1002
|
}
|
|
947
1003
|
}
|
|
948
1004
|
|
|
949
|
-
|
|
1005
|
+
// Copy attachment files if feature is enabled
|
|
1006
|
+
if (config.features?.attachments !== false) {
|
|
1007
|
+
console.log(chalk.blue('\n📎 Processing attachments...'));
|
|
1008
|
+
|
|
1009
|
+
const attachmentTypes = config.attachmentTypes || [
|
|
1010
|
+
'.pdf', '.doc', '.docx', '.xls', '.xlsx', '.csv', '.ppt', '.pptx', '.txt', '.rtf',
|
|
1011
|
+
'.zip', '.tar', '.gz', '.7z', '.rar',
|
|
1012
|
+
'.png', '.jpg', '.jpeg', '.gif', '.svg', '.webp', '.ico', '.bmp',
|
|
1013
|
+
'.json', '.xml', '.yaml', '.yml', '.toml',
|
|
1014
|
+
'.mp4', '.mp3', '.wav', '.avi', '.mov'
|
|
1015
|
+
];
|
|
1016
|
+
|
|
1017
|
+
try {
|
|
1018
|
+
const attachmentFiles = await getAllAttachmentFiles(docsDir, docsDir, attachmentTypes);
|
|
1019
|
+
|
|
1020
|
+
if (attachmentFiles.length > 0) {
|
|
1021
|
+
const { copiedCount, totalSize } = await copyAttachmentFiles(attachmentFiles, docsDir, outputDir);
|
|
1022
|
+
|
|
1023
|
+
// Format file size
|
|
1024
|
+
const formatSize = (bytes) => {
|
|
1025
|
+
if (bytes < 1024) return bytes + ' B';
|
|
1026
|
+
if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + ' KB';
|
|
1027
|
+
return (bytes / (1024 * 1024)).toFixed(1) + ' MB';
|
|
1028
|
+
};
|
|
1029
|
+
|
|
1030
|
+
console.log(chalk.green(`✅ Copied ${copiedCount} attachments (${formatSize(totalSize)} total)`));
|
|
1031
|
+
} else {
|
|
1032
|
+
console.log(chalk.gray(' No attachments found to copy'));
|
|
1033
|
+
}
|
|
1034
|
+
} catch (error) {
|
|
1035
|
+
console.warn(chalk.yellow(`Warning: Error processing attachments: ${error.message}`));
|
|
1036
|
+
}
|
|
1037
|
+
}
|
|
1038
|
+
|
|
1039
|
+
console.log(chalk.green('\n✅ Documentation build complete!'));
|
|
950
1040
|
}
|
|
951
1041
|
|
|
952
1042
|
// Create placeholder README.md if missing
|
package/manage-users.sql
ADDED
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
-- =====================================================
|
|
2
|
+
-- USER MANAGEMENT SQL COMMANDS FOR DOC-BUILDER
|
|
3
|
+
-- =====================================================
|
|
4
|
+
-- Run these in your Supabase SQL Editor
|
|
5
|
+
|
|
6
|
+
-- =====================================================
|
|
7
|
+
-- 1. VIEW YOUR SITES
|
|
8
|
+
-- =====================================================
|
|
9
|
+
-- See all your documentation sites
|
|
10
|
+
SELECT id, domain, name, created_at
|
|
11
|
+
FROM docbuilder_sites
|
|
12
|
+
ORDER BY created_at DESC;
|
|
13
|
+
|
|
14
|
+
-- =====================================================
|
|
15
|
+
-- 2. VIEW EXISTING USERS
|
|
16
|
+
-- =====================================================
|
|
17
|
+
-- See all users in your Supabase project
|
|
18
|
+
SELECT id, email, created_at, last_sign_in_at
|
|
19
|
+
FROM auth.users
|
|
20
|
+
ORDER BY created_at DESC;
|
|
21
|
+
|
|
22
|
+
-- =====================================================
|
|
23
|
+
-- 3. VIEW WHO HAS ACCESS TO A SPECIFIC SITE
|
|
24
|
+
-- =====================================================
|
|
25
|
+
-- Replace 'your-site-id' with actual site ID
|
|
26
|
+
SELECT
|
|
27
|
+
u.email,
|
|
28
|
+
u.id as user_id,
|
|
29
|
+
u.created_at as user_since,
|
|
30
|
+
da.created_at as access_granted,
|
|
31
|
+
ds.name as site_name,
|
|
32
|
+
ds.domain
|
|
33
|
+
FROM docbuilder_access da
|
|
34
|
+
JOIN auth.users u ON u.id = da.user_id
|
|
35
|
+
JOIN docbuilder_sites ds ON ds.id = da.site_id
|
|
36
|
+
WHERE da.site_id = 'your-site-id'
|
|
37
|
+
ORDER BY da.created_at DESC;
|
|
38
|
+
|
|
39
|
+
-- =====================================================
|
|
40
|
+
-- 4. ADD A SINGLE USER TO A SITE
|
|
41
|
+
-- =====================================================
|
|
42
|
+
-- First, create user in Supabase Dashboard (Authentication > Users > Invite)
|
|
43
|
+
-- Then grant access:
|
|
44
|
+
INSERT INTO docbuilder_access (user_id, site_id)
|
|
45
|
+
VALUES (
|
|
46
|
+
(SELECT id FROM auth.users WHERE email = 'user@example.com'),
|
|
47
|
+
'your-site-id'
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
-- =====================================================
|
|
51
|
+
-- 5. ADD MULTIPLE USERS TO A SITE
|
|
52
|
+
-- =====================================================
|
|
53
|
+
-- Add a list of users all at once
|
|
54
|
+
WITH users_to_add AS (
|
|
55
|
+
SELECT email FROM (VALUES
|
|
56
|
+
('user1@example.com'),
|
|
57
|
+
('user2@example.com'),
|
|
58
|
+
('user3@example.com'),
|
|
59
|
+
('user4@example.com')
|
|
60
|
+
) AS t(email)
|
|
61
|
+
)
|
|
62
|
+
INSERT INTO docbuilder_access (user_id, site_id)
|
|
63
|
+
SELECT u.id, 'your-site-id'
|
|
64
|
+
FROM auth.users u
|
|
65
|
+
JOIN users_to_add ua ON u.email = ua.email
|
|
66
|
+
WHERE NOT EXISTS (
|
|
67
|
+
-- Prevent duplicate entries
|
|
68
|
+
SELECT 1 FROM docbuilder_access
|
|
69
|
+
WHERE user_id = u.id AND site_id = 'your-site-id'
|
|
70
|
+
);
|
|
71
|
+
|
|
72
|
+
-- =====================================================
|
|
73
|
+
-- 6. GRANT USER ACCESS TO MULTIPLE SITES
|
|
74
|
+
-- =====================================================
|
|
75
|
+
-- Give one user access to several sites
|
|
76
|
+
WITH sites_to_grant AS (
|
|
77
|
+
SELECT id FROM docbuilder_sites
|
|
78
|
+
WHERE domain IN ('site1.com', 'site2.com', 'site3.com')
|
|
79
|
+
)
|
|
80
|
+
INSERT INTO docbuilder_access (user_id, site_id)
|
|
81
|
+
SELECT
|
|
82
|
+
(SELECT id FROM auth.users WHERE email = 'user@example.com'),
|
|
83
|
+
s.id
|
|
84
|
+
FROM sites_to_grant s
|
|
85
|
+
WHERE NOT EXISTS (
|
|
86
|
+
SELECT 1 FROM docbuilder_access
|
|
87
|
+
WHERE user_id = (SELECT id FROM auth.users WHERE email = 'user@example.com')
|
|
88
|
+
AND site_id = s.id
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
-- =====================================================
|
|
92
|
+
-- 7. REMOVE USER ACCESS FROM A SITE
|
|
93
|
+
-- =====================================================
|
|
94
|
+
-- Remove specific user from specific site
|
|
95
|
+
DELETE FROM docbuilder_access
|
|
96
|
+
WHERE user_id = (SELECT id FROM auth.users WHERE email = 'user@example.com')
|
|
97
|
+
AND site_id = 'your-site-id';
|
|
98
|
+
|
|
99
|
+
-- =====================================================
|
|
100
|
+
-- 8. REMOVE USER FROM ALL SITES
|
|
101
|
+
-- =====================================================
|
|
102
|
+
-- Completely remove user's access to all documentation
|
|
103
|
+
DELETE FROM docbuilder_access
|
|
104
|
+
WHERE user_id = (SELECT id FROM auth.users WHERE email = 'user@example.com');
|
|
105
|
+
|
|
106
|
+
-- =====================================================
|
|
107
|
+
-- 9. BULK REMOVE USERS
|
|
108
|
+
-- =====================================================
|
|
109
|
+
-- Remove multiple users from a site
|
|
110
|
+
WITH users_to_remove AS (
|
|
111
|
+
SELECT email FROM (VALUES
|
|
112
|
+
('olduser1@example.com'),
|
|
113
|
+
('olduser2@example.com')
|
|
114
|
+
) AS t(email)
|
|
115
|
+
)
|
|
116
|
+
DELETE FROM docbuilder_access
|
|
117
|
+
WHERE site_id = 'your-site-id'
|
|
118
|
+
AND user_id IN (
|
|
119
|
+
SELECT u.id FROM auth.users u
|
|
120
|
+
JOIN users_to_remove ur ON u.email = ur.email
|
|
121
|
+
);
|
|
122
|
+
|
|
123
|
+
-- =====================================================
|
|
124
|
+
-- 10. VIEW ACCESS SUMMARY
|
|
125
|
+
-- =====================================================
|
|
126
|
+
-- See how many users each site has
|
|
127
|
+
SELECT
|
|
128
|
+
ds.name as site_name,
|
|
129
|
+
ds.domain,
|
|
130
|
+
ds.id as site_id,
|
|
131
|
+
COUNT(da.user_id) as user_count,
|
|
132
|
+
MAX(da.created_at) as last_access_granted
|
|
133
|
+
FROM docbuilder_sites ds
|
|
134
|
+
LEFT JOIN docbuilder_access da ON ds.id = da.site_id
|
|
135
|
+
GROUP BY ds.id, ds.name, ds.domain
|
|
136
|
+
ORDER BY user_count DESC;
|
|
137
|
+
|
|
138
|
+
-- =====================================================
|
|
139
|
+
-- 11. FIND USERS WITHOUT ACCESS TO ANY SITE
|
|
140
|
+
-- =====================================================
|
|
141
|
+
-- Useful for cleanup
|
|
142
|
+
SELECT u.email, u.created_at, u.last_sign_in_at
|
|
143
|
+
FROM auth.users u
|
|
144
|
+
WHERE NOT EXISTS (
|
|
145
|
+
SELECT 1 FROM docbuilder_access da
|
|
146
|
+
WHERE da.user_id = u.id
|
|
147
|
+
)
|
|
148
|
+
ORDER BY u.created_at DESC;
|
|
149
|
+
|
|
150
|
+
-- =====================================================
|
|
151
|
+
-- 12. AUDIT LOG - RECENT ACCESS GRANTS
|
|
152
|
+
-- =====================================================
|
|
153
|
+
-- See who was granted access recently
|
|
154
|
+
SELECT
|
|
155
|
+
u.email,
|
|
156
|
+
ds.name as site_name,
|
|
157
|
+
ds.domain,
|
|
158
|
+
da.created_at as access_granted
|
|
159
|
+
FROM docbuilder_access da
|
|
160
|
+
JOIN auth.users u ON u.id = da.user_id
|
|
161
|
+
JOIN docbuilder_sites ds ON ds.id = da.site_id
|
|
162
|
+
WHERE da.created_at > NOW() - INTERVAL '30 days'
|
|
163
|
+
ORDER BY da.created_at DESC;
|
|
164
|
+
|
|
165
|
+
-- =====================================================
|
|
166
|
+
-- 13. COPY ACCESS FROM ONE USER TO ANOTHER
|
|
167
|
+
-- =====================================================
|
|
168
|
+
-- Useful when replacing team members
|
|
169
|
+
INSERT INTO docbuilder_access (user_id, site_id)
|
|
170
|
+
SELECT
|
|
171
|
+
(SELECT id FROM auth.users WHERE email = 'newuser@example.com'),
|
|
172
|
+
da.site_id
|
|
173
|
+
FROM docbuilder_access da
|
|
174
|
+
WHERE da.user_id = (SELECT id FROM auth.users WHERE email = 'olduser@example.com');
|
|
175
|
+
|
|
176
|
+
-- =====================================================
|
|
177
|
+
-- COMMON SITE IDs FOR REFERENCE
|
|
178
|
+
-- =====================================================
|
|
179
|
+
-- Your test site: 4d8a53bf-dcdd-48c0-98e0-cd1451518735
|
|
180
|
+
-- Add more site IDs here as you create them:
|
|
181
|
+
-- Production site: xxx
|
|
182
|
+
-- Staging site: xxx
|
|
183
|
+
|
|
184
|
+
-- =====================================================
|
|
185
|
+
-- TIPS
|
|
186
|
+
-- =====================================================
|
|
187
|
+
-- 1. Always check if users exist before granting access
|
|
188
|
+
-- 2. Use the Supabase Dashboard to invite new users first
|
|
189
|
+
-- 3. Run SELECT queries before DELETE to verify
|
|
190
|
+
-- 4. Keep this file updated with your site IDs
|
|
191
|
+
-- 5. Consider creating views for common queries
|
package/package.json
CHANGED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
-- =====================================================
|
|
2
|
+
-- VIEW ALL USERS WITH ACCESS
|
|
3
|
+
-- Site: https://wru-bid-analysis.vercel.app/
|
|
4
|
+
-- =====================================================
|
|
5
|
+
|
|
6
|
+
-- See everyone who has access to the WRU site
|
|
7
|
+
SELECT
|
|
8
|
+
u.email,
|
|
9
|
+
u.created_at as user_created,
|
|
10
|
+
da.created_at as access_granted,
|
|
11
|
+
CASE
|
|
12
|
+
WHEN u.last_sign_in_at IS NULL THEN '❌ Never logged in'
|
|
13
|
+
ELSE '✅ Has logged in'
|
|
14
|
+
END as login_status,
|
|
15
|
+
u.last_sign_in_at
|
|
16
|
+
FROM docbuilder_access da
|
|
17
|
+
JOIN auth.users u ON u.id = da.user_id
|
|
18
|
+
WHERE da.site_id = '4d8a53bf-dcdd-48c0-98e0-cd1451518735'
|
|
19
|
+
ORDER BY da.created_at DESC;
|
|
20
|
+
|
|
21
|
+
-- Count total users with access
|
|
22
|
+
SELECT COUNT(*) as total_users_with_access
|
|
23
|
+
FROM docbuilder_access
|
|
24
|
+
WHERE site_id = '4d8a53bf-dcdd-48c0-98e0-cd1451518735';
|
|
25
|
+
|
|
26
|
+
-- Check which of the 4 users exist in Supabase
|
|
27
|
+
SELECT
|
|
28
|
+
email,
|
|
29
|
+
CASE
|
|
30
|
+
WHEN id IS NOT NULL THEN '✅ User exists'
|
|
31
|
+
ELSE '❌ Not created yet'
|
|
32
|
+
END as status
|
|
33
|
+
FROM (
|
|
34
|
+
VALUES
|
|
35
|
+
('lindsay@knowcode.tech'),
|
|
36
|
+
('pmorgan@wru.cymru'),
|
|
37
|
+
('clive@hyperforma.co.uk'),
|
|
38
|
+
('robbie.macintosh@marbledropper.com')
|
|
39
|
+
) AS emails(email)
|
|
40
|
+
LEFT JOIN auth.users u ON u.email = emails.email;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// doc-builder.config.js - Configuration with Supabase Authentication
|
|
2
|
+
module.exports = {
|
|
3
|
+
siteName: 'WRU Bid Analysis Documentation',
|
|
4
|
+
siteDescription: 'Analysis and documentation for WRU bidding process',
|
|
5
|
+
|
|
6
|
+
// Enable Supabase authentication
|
|
7
|
+
features: {
|
|
8
|
+
authentication: 'supabase' // This turns on auth (set to false for public)
|
|
9
|
+
},
|
|
10
|
+
|
|
11
|
+
// Supabase configuration
|
|
12
|
+
auth: {
|
|
13
|
+
supabaseUrl: 'https://xcihhnfcitjrwbynxmka.supabase.co',
|
|
14
|
+
supabaseAnonKey: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InhjaWhobmZjaXRqcndieW54bWthIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTM0Mzc2MzcsImV4cCI6MjA2OTAxMzYzN30.zvWp3JFIR8fBIiwuFF5gqOR_Kxb42baZS5fsBz60XOY',
|
|
15
|
+
siteId: '4d8a53bf-dcdd-48c0-98e0-cd1451518735'
|
|
16
|
+
}
|
|
17
|
+
};
|
package/assets/js/auth.js
DELETED
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Simple Client-Side Authentication for Documentation
|
|
3
|
-
* This runs on every page load to check authentication
|
|
4
|
-
*
|
|
5
|
-
* IMPORTANT: This is a basic authentication system suitable for
|
|
6
|
-
* protecting documentation from casual access. For production
|
|
7
|
-
* use with sensitive data, implement server-side authentication.
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
(function() {
|
|
11
|
-
'use strict';
|
|
12
|
-
|
|
13
|
-
// Skip auth check on login and logout pages
|
|
14
|
-
const currentPage = window.location.pathname;
|
|
15
|
-
if (currentPage === '/login.html' || currentPage === '/logout.html' || currentPage.includes('login') || currentPage.includes('logout')) {
|
|
16
|
-
return;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
// Check if user is authenticated
|
|
20
|
-
function isAuthenticated() {
|
|
21
|
-
const authToken = getCookie('doc-auth');
|
|
22
|
-
if (!authToken) return false;
|
|
23
|
-
|
|
24
|
-
try {
|
|
25
|
-
// Simple token validation - just check if it exists and has expected format
|
|
26
|
-
// The actual validation happens server-side (or in login page for static sites)
|
|
27
|
-
const decoded = atob(authToken);
|
|
28
|
-
return decoded && decoded.includes(':');
|
|
29
|
-
} catch (error) {
|
|
30
|
-
return false;
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
// Get cookie value
|
|
35
|
-
function getCookie(name) {
|
|
36
|
-
const value = `; ${document.cookie}`;
|
|
37
|
-
const parts = value.split(`; ${name}=`);
|
|
38
|
-
if (parts.length === 2) return parts.pop().split(';').shift();
|
|
39
|
-
return null;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
// Redirect to login if not authenticated
|
|
43
|
-
function redirectToLogin() {
|
|
44
|
-
const currentUrl = window.location.pathname + window.location.search;
|
|
45
|
-
const loginUrl = '/login.html' + (currentUrl !== '/' ? '?redirect=' + encodeURIComponent(currentUrl) : '');
|
|
46
|
-
window.location.href = loginUrl;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
// Check authentication on page load
|
|
50
|
-
if (!isAuthenticated()) {
|
|
51
|
-
redirectToLogin();
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
// Add logout functionality to logout buttons
|
|
55
|
-
document.addEventListener('DOMContentLoaded', function() {
|
|
56
|
-
const logoutLinks = document.querySelectorAll('a[href*="logout"]');
|
|
57
|
-
logoutLinks.forEach(link => {
|
|
58
|
-
link.addEventListener('click', function(e) {
|
|
59
|
-
e.preventDefault();
|
|
60
|
-
// Clear auth cookie
|
|
61
|
-
document.cookie = 'doc-auth=; path=/; expires=Thu, 01 Jan 1970 00:00:01 GMT;';
|
|
62
|
-
window.location.href = '/logout.html';
|
|
63
|
-
});
|
|
64
|
-
});
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
})();
|