@knowcode/doc-builder 1.7.6 → 1.8.0
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/.claude/settings.local.json +3 -1
- package/CHANGELOG.md +22 -0
- package/assets/css/notion-style.css +9 -1
- package/html/README.html +5 -19
- package/html/css/notion-style.css +9 -1
- package/html/documentation-index.html +5 -19
- package/html/guides/authentication-default-change.html +5 -19
- package/html/guides/authentication-guide.html +189 -262
- package/html/guides/claude-workflow-guide.html +5 -19
- package/html/guides/documentation-standards.html +5 -19
- package/html/guides/phosphor-icons-guide.html +5 -19
- package/html/guides/private-directory-authentication.html +352 -0
- package/html/guides/public-site-deployment.html +11 -24
- package/html/guides/search-engine-verification-guide.html +5 -19
- package/html/guides/seo-guide.html +5 -19
- package/html/guides/seo-optimization-guide.html +5 -19
- package/html/guides/troubleshooting-guide.html +5 -19
- package/html/guides/windows-setup-guide.html +5 -19
- package/html/index.html +5 -19
- package/html/private/cache-control-anti-pattern.html +347 -0
- package/html/private/launch/README.html +289 -0
- package/html/private/launch/auth-cleanup-summary.html +279 -0
- package/html/private/launch/bubble-plugin-specification.html +925 -0
- package/html/private/launch/go-to-market-strategy.html +655 -0
- package/html/private/launch/launch-announcements.html +585 -0
- package/html/private/launch/vercel-deployment-auth-setup.html +329 -0
- package/html/private/next-steps-walkthrough.html +624 -0
- package/html/private/supabase-auth-implementation-completed.html +372 -0
- package/html/private/supabase-auth-implementation-plan.html +529 -0
- package/html/private/supabase-auth-integration-plan.html +657 -0
- package/html/private/supabase-auth-setup-guide.html +484 -0
- package/html/private/test-private-doc.html +220 -0
- package/html/sitemap.xml +113 -29
- package/html/vercel-cli-setup-guide.html +5 -19
- package/html/vercel-first-time-setup-guide.html +5 -19
- package/lib/config.js +24 -0
- package/lib/core-builder.js +40 -6
- package/lib/supabase-auth.js +60 -11
- package/package.json +1 -1
- package/user-management/README.md +81 -0
- package/user-management/add-users.sh +357 -0
- package/user-management/users.txt +15 -0
|
@@ -0,0 +1,357 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# Simple User Management Script for doc-builder
|
|
4
|
+
# This script helps manage users for Supabase authenticated documentation sites
|
|
5
|
+
|
|
6
|
+
set -e
|
|
7
|
+
|
|
8
|
+
# Colors for output
|
|
9
|
+
RED='\033[0;31m'
|
|
10
|
+
GREEN='\033[0;32m'
|
|
11
|
+
YELLOW='\033[1;33m'
|
|
12
|
+
BLUE='\033[0;34m'
|
|
13
|
+
NC='\033[0m' # No Color
|
|
14
|
+
|
|
15
|
+
# Default to environment variable or empty
|
|
16
|
+
SITE_URL="${DOC_SITE_URL:-}"
|
|
17
|
+
|
|
18
|
+
# Help function
|
|
19
|
+
show_help() {
|
|
20
|
+
echo -e "${BLUE}Doc-Builder User Management${NC}"
|
|
21
|
+
echo ""
|
|
22
|
+
echo "Usage: $0 <command> [options]"
|
|
23
|
+
echo ""
|
|
24
|
+
echo "Commands:"
|
|
25
|
+
echo " add <site-url> <email> Add a single user to a site"
|
|
26
|
+
echo " bulk <site-url> <file> Add multiple users from a file"
|
|
27
|
+
echo " list <site-url> List all users with access to a site"
|
|
28
|
+
echo " check <site-url> <email> Check if a user has access to a site"
|
|
29
|
+
echo " remove <site-url> <email> Remove user access from a site"
|
|
30
|
+
echo " sites List all documentation sites"
|
|
31
|
+
echo " sql Generate SQL command templates"
|
|
32
|
+
echo ""
|
|
33
|
+
echo "Examples:"
|
|
34
|
+
echo " $0 add wru-bid-analysis.vercel.app john@example.com"
|
|
35
|
+
echo " $0 bulk my-docs.vercel.app users.txt"
|
|
36
|
+
echo " $0 list wru-bid-analysis.vercel.app"
|
|
37
|
+
echo " $0 check my-docs.vercel.app john@example.com"
|
|
38
|
+
echo ""
|
|
39
|
+
echo "Environment Variables:"
|
|
40
|
+
echo " DOC_SITE_URL Default site URL (optional)"
|
|
41
|
+
echo ""
|
|
42
|
+
echo "Note: Site URLs should be without https:// prefix"
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
# Generate SQL for listing all sites
|
|
46
|
+
generate_sites_sql() {
|
|
47
|
+
cat << EOF
|
|
48
|
+
|
|
49
|
+
-- =====================================================
|
|
50
|
+
-- LIST ALL DOCUMENTATION SITES
|
|
51
|
+
-- Generated: $(date)
|
|
52
|
+
-- =====================================================
|
|
53
|
+
|
|
54
|
+
SELECT
|
|
55
|
+
id as site_id,
|
|
56
|
+
domain,
|
|
57
|
+
name,
|
|
58
|
+
created_at,
|
|
59
|
+
(SELECT COUNT(*) FROM docbuilder_access WHERE site_id = docbuilder_sites.id) as user_count
|
|
60
|
+
FROM docbuilder_sites
|
|
61
|
+
ORDER BY created_at DESC;
|
|
62
|
+
|
|
63
|
+
EOF
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
# Generate SQL for adding a user
|
|
67
|
+
generate_add_sql() {
|
|
68
|
+
local site_url=$1
|
|
69
|
+
local email=$2
|
|
70
|
+
cat << EOF
|
|
71
|
+
|
|
72
|
+
-- =====================================================
|
|
73
|
+
-- ADD USER: ${email}
|
|
74
|
+
-- Site: ${site_url}
|
|
75
|
+
-- Generated: $(date)
|
|
76
|
+
-- =====================================================
|
|
77
|
+
|
|
78
|
+
-- Step 1: Get site ID from URL
|
|
79
|
+
WITH site_info AS (
|
|
80
|
+
SELECT id, name FROM docbuilder_sites WHERE domain = '${site_url}'
|
|
81
|
+
)
|
|
82
|
+
SELECT * FROM site_info;
|
|
83
|
+
|
|
84
|
+
-- Step 2: Check if user exists
|
|
85
|
+
SELECT id, email, created_at FROM auth.users WHERE email = '${email}';
|
|
86
|
+
|
|
87
|
+
-- Step 3: If user doesn't exist, create them in Supabase Dashboard:
|
|
88
|
+
-- https://supabase.com/dashboard/project/xcihhnfcitjrwbynxmka/auth/users
|
|
89
|
+
-- Click "Invite user" and enter: ${email}
|
|
90
|
+
|
|
91
|
+
-- Step 4: Grant access (run after user is created)
|
|
92
|
+
INSERT INTO docbuilder_access (user_id, site_id)
|
|
93
|
+
SELECT
|
|
94
|
+
(SELECT id FROM auth.users WHERE email = '${email}'),
|
|
95
|
+
(SELECT id FROM docbuilder_sites WHERE domain = '${site_url}')
|
|
96
|
+
WHERE EXISTS (SELECT 1 FROM auth.users WHERE email = '${email}')
|
|
97
|
+
AND EXISTS (SELECT 1 FROM docbuilder_sites WHERE domain = '${site_url}')
|
|
98
|
+
AND NOT EXISTS (
|
|
99
|
+
SELECT 1 FROM docbuilder_access
|
|
100
|
+
WHERE user_id = (SELECT id FROM auth.users WHERE email = '${email}')
|
|
101
|
+
AND site_id = (SELECT id FROM docbuilder_sites WHERE domain = '${site_url}')
|
|
102
|
+
);
|
|
103
|
+
|
|
104
|
+
-- Step 5: Verify access was granted
|
|
105
|
+
SELECT
|
|
106
|
+
u.email,
|
|
107
|
+
s.name as site_name,
|
|
108
|
+
s.domain as site_url,
|
|
109
|
+
da.created_at as access_granted
|
|
110
|
+
FROM docbuilder_access da
|
|
111
|
+
JOIN auth.users u ON u.id = da.user_id
|
|
112
|
+
JOIN docbuilder_sites s ON s.id = da.site_id
|
|
113
|
+
WHERE u.email = '${email}' AND s.domain = '${site_url}';
|
|
114
|
+
|
|
115
|
+
EOF
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
# Generate SQL for listing users
|
|
119
|
+
generate_list_sql() {
|
|
120
|
+
local site_url=$1
|
|
121
|
+
cat << EOF
|
|
122
|
+
|
|
123
|
+
-- =====================================================
|
|
124
|
+
-- LIST ALL USERS WITH ACCESS
|
|
125
|
+
-- Site: ${site_url}
|
|
126
|
+
-- Generated: $(date)
|
|
127
|
+
-- =====================================================
|
|
128
|
+
|
|
129
|
+
SELECT
|
|
130
|
+
u.email,
|
|
131
|
+
u.created_at as user_created,
|
|
132
|
+
da.created_at as access_granted,
|
|
133
|
+
CASE
|
|
134
|
+
WHEN u.last_sign_in_at IS NULL THEN 'Never logged in'
|
|
135
|
+
ELSE 'Last login: ' || u.last_sign_in_at::text
|
|
136
|
+
END as login_status
|
|
137
|
+
FROM docbuilder_access da
|
|
138
|
+
JOIN auth.users u ON u.id = da.user_id
|
|
139
|
+
JOIN docbuilder_sites s ON s.id = da.site_id
|
|
140
|
+
WHERE s.domain = '${site_url}'
|
|
141
|
+
ORDER BY da.created_at DESC;
|
|
142
|
+
|
|
143
|
+
-- Site info
|
|
144
|
+
SELECT name, domain, created_at
|
|
145
|
+
FROM docbuilder_sites
|
|
146
|
+
WHERE domain = '${site_url}';
|
|
147
|
+
|
|
148
|
+
EOF
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
# Generate SQL for checking a user
|
|
152
|
+
generate_check_sql() {
|
|
153
|
+
local site_url=$1
|
|
154
|
+
local email=$2
|
|
155
|
+
cat << EOF
|
|
156
|
+
|
|
157
|
+
-- =====================================================
|
|
158
|
+
-- CHECK USER: ${email}
|
|
159
|
+
-- Site: ${site_url}
|
|
160
|
+
-- Generated: $(date)
|
|
161
|
+
-- =====================================================
|
|
162
|
+
|
|
163
|
+
-- Check if user exists
|
|
164
|
+
SELECT
|
|
165
|
+
id,
|
|
166
|
+
email,
|
|
167
|
+
created_at,
|
|
168
|
+
last_sign_in_at,
|
|
169
|
+
CASE
|
|
170
|
+
WHEN last_sign_in_at IS NULL THEN 'Never logged in'
|
|
171
|
+
ELSE 'Last login: ' || last_sign_in_at::text
|
|
172
|
+
END as login_status
|
|
173
|
+
FROM auth.users
|
|
174
|
+
WHERE email = '${email}';
|
|
175
|
+
|
|
176
|
+
-- Check if user has access to this site
|
|
177
|
+
SELECT
|
|
178
|
+
s.name as site_name,
|
|
179
|
+
s.domain as site_url,
|
|
180
|
+
'Has Access' as status,
|
|
181
|
+
da.created_at as access_granted
|
|
182
|
+
FROM docbuilder_access da
|
|
183
|
+
JOIN auth.users u ON u.id = da.user_id
|
|
184
|
+
JOIN docbuilder_sites s ON s.id = da.site_id
|
|
185
|
+
WHERE u.email = '${email}' AND s.domain = '${site_url}';
|
|
186
|
+
|
|
187
|
+
-- List all sites this user has access to
|
|
188
|
+
SELECT
|
|
189
|
+
s.name as site_name,
|
|
190
|
+
s.domain as site_url,
|
|
191
|
+
da.created_at as access_granted
|
|
192
|
+
FROM docbuilder_access da
|
|
193
|
+
JOIN auth.users u ON u.id = da.user_id
|
|
194
|
+
JOIN docbuilder_sites s ON s.id = da.site_id
|
|
195
|
+
WHERE u.email = '${email}'
|
|
196
|
+
ORDER BY da.created_at DESC;
|
|
197
|
+
|
|
198
|
+
EOF
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
# Generate SQL for removing user access
|
|
202
|
+
generate_remove_sql() {
|
|
203
|
+
local site_url=$1
|
|
204
|
+
local email=$2
|
|
205
|
+
cat << EOF
|
|
206
|
+
|
|
207
|
+
-- =====================================================
|
|
208
|
+
-- REMOVE USER ACCESS: ${email}
|
|
209
|
+
-- Site: ${site_url}
|
|
210
|
+
-- Generated: $(date)
|
|
211
|
+
-- =====================================================
|
|
212
|
+
|
|
213
|
+
-- Remove access (does not delete user account)
|
|
214
|
+
DELETE FROM docbuilder_access
|
|
215
|
+
WHERE user_id = (SELECT id FROM auth.users WHERE email = '${email}')
|
|
216
|
+
AND site_id = (SELECT id FROM docbuilder_sites WHERE domain = '${site_url}');
|
|
217
|
+
|
|
218
|
+
-- Verify removal
|
|
219
|
+
SELECT
|
|
220
|
+
CASE
|
|
221
|
+
WHEN COUNT(*) = 0 THEN 'Access removed successfully'
|
|
222
|
+
ELSE 'ERROR: User still has access'
|
|
223
|
+
END as status
|
|
224
|
+
FROM docbuilder_access da
|
|
225
|
+
JOIN auth.users u ON u.id = da.user_id
|
|
226
|
+
JOIN docbuilder_sites s ON s.id = da.site_id
|
|
227
|
+
WHERE u.email = '${email}' AND s.domain = '${site_url}';
|
|
228
|
+
|
|
229
|
+
-- Show remaining sites for this user
|
|
230
|
+
SELECT
|
|
231
|
+
s.name as site_name,
|
|
232
|
+
s.domain as site_url,
|
|
233
|
+
da.created_at as access_granted
|
|
234
|
+
FROM docbuilder_access da
|
|
235
|
+
JOIN auth.users u ON u.id = da.user_id
|
|
236
|
+
JOIN docbuilder_sites s ON s.id = da.site_id
|
|
237
|
+
WHERE u.email = '${email}'
|
|
238
|
+
ORDER BY da.created_at DESC;
|
|
239
|
+
|
|
240
|
+
EOF
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
# Main script logic
|
|
244
|
+
case "$1" in
|
|
245
|
+
add)
|
|
246
|
+
if [ -z "$2" ] || [ -z "$3" ]; then
|
|
247
|
+
echo -e "${RED}Error: Missing parameters${NC}"
|
|
248
|
+
echo "Usage: $0 add <site-url> <email>"
|
|
249
|
+
echo "Example: $0 add wru-bid-analysis.vercel.app john@example.com"
|
|
250
|
+
exit 1
|
|
251
|
+
fi
|
|
252
|
+
site_url="$2"
|
|
253
|
+
email="$3"
|
|
254
|
+
echo -e "${BLUE}Adding user: $email to site: $site_url${NC}"
|
|
255
|
+
generate_add_sql "$site_url" "$email"
|
|
256
|
+
echo -e "${YELLOW}Copy and run the SQL above in Supabase SQL Editor${NC}"
|
|
257
|
+
echo -e "${YELLOW}Dashboard: https://supabase.com/dashboard/project/xcihhnfcitjrwbynxmka/sql${NC}"
|
|
258
|
+
;;
|
|
259
|
+
|
|
260
|
+
bulk)
|
|
261
|
+
if [ -z "$2" ] || [ -z "$3" ]; then
|
|
262
|
+
echo -e "${RED}Error: Missing parameters${NC}"
|
|
263
|
+
echo "Usage: $0 bulk <site-url> <file>"
|
|
264
|
+
echo "Example: $0 bulk wru-bid-analysis.vercel.app users.txt"
|
|
265
|
+
exit 1
|
|
266
|
+
fi
|
|
267
|
+
site_url="$2"
|
|
268
|
+
file_path="$3"
|
|
269
|
+
if [ ! -f "$file_path" ]; then
|
|
270
|
+
echo -e "${RED}Error: File not found: $file_path${NC}"
|
|
271
|
+
exit 1
|
|
272
|
+
fi
|
|
273
|
+
echo -e "${BLUE}Generating SQL for users in $file_path for site: $site_url${NC}"
|
|
274
|
+
while IFS= read -r email; do
|
|
275
|
+
# Skip empty lines and comments
|
|
276
|
+
[[ -z "$email" || "$email" =~ ^#.*$ ]] && continue
|
|
277
|
+
# Trim whitespace
|
|
278
|
+
email=$(echo "$email" | xargs)
|
|
279
|
+
generate_add_sql "$site_url" "$email"
|
|
280
|
+
done < "$file_path"
|
|
281
|
+
echo -e "${YELLOW}Copy and run the SQL above in Supabase SQL Editor${NC}"
|
|
282
|
+
echo -e "${YELLOW}Dashboard: https://supabase.com/dashboard/project/xcihhnfcitjrwbynxmka/sql${NC}"
|
|
283
|
+
;;
|
|
284
|
+
|
|
285
|
+
list)
|
|
286
|
+
if [ -z "$2" ]; then
|
|
287
|
+
echo -e "${RED}Error: Missing site URL${NC}"
|
|
288
|
+
echo "Usage: $0 list <site-url>"
|
|
289
|
+
echo "Example: $0 list wru-bid-analysis.vercel.app"
|
|
290
|
+
exit 1
|
|
291
|
+
fi
|
|
292
|
+
site_url="$2"
|
|
293
|
+
echo -e "${BLUE}Listing all users with access to: $site_url${NC}"
|
|
294
|
+
generate_list_sql "$site_url"
|
|
295
|
+
echo -e "${YELLOW}Copy and run the SQL above in Supabase SQL Editor${NC}"
|
|
296
|
+
echo -e "${YELLOW}Dashboard: https://supabase.com/dashboard/project/xcihhnfcitjrwbynxmka/sql${NC}"
|
|
297
|
+
;;
|
|
298
|
+
|
|
299
|
+
check)
|
|
300
|
+
if [ -z "$2" ] || [ -z "$3" ]; then
|
|
301
|
+
echo -e "${RED}Error: Missing parameters${NC}"
|
|
302
|
+
echo "Usage: $0 check <site-url> <email>"
|
|
303
|
+
echo "Example: $0 check wru-bid-analysis.vercel.app john@example.com"
|
|
304
|
+
exit 1
|
|
305
|
+
fi
|
|
306
|
+
site_url="$2"
|
|
307
|
+
email="$3"
|
|
308
|
+
echo -e "${BLUE}Checking user: $email for site: $site_url${NC}"
|
|
309
|
+
generate_check_sql "$site_url" "$email"
|
|
310
|
+
echo -e "${YELLOW}Copy and run the SQL above in Supabase SQL Editor${NC}"
|
|
311
|
+
echo -e "${YELLOW}Dashboard: https://supabase.com/dashboard/project/xcihhnfcitjrwbynxmka/sql${NC}"
|
|
312
|
+
;;
|
|
313
|
+
|
|
314
|
+
remove)
|
|
315
|
+
if [ -z "$2" ] || [ -z "$3" ]; then
|
|
316
|
+
echo -e "${RED}Error: Missing parameters${NC}"
|
|
317
|
+
echo "Usage: $0 remove <site-url> <email>"
|
|
318
|
+
echo "Example: $0 remove wru-bid-analysis.vercel.app john@example.com"
|
|
319
|
+
exit 1
|
|
320
|
+
fi
|
|
321
|
+
site_url="$2"
|
|
322
|
+
email="$3"
|
|
323
|
+
echo -e "${BLUE}Removing access for user: $email from site: $site_url${NC}"
|
|
324
|
+
generate_remove_sql "$site_url" "$email"
|
|
325
|
+
echo -e "${YELLOW}Copy and run the SQL above in Supabase SQL Editor${NC}"
|
|
326
|
+
echo -e "${YELLOW}Dashboard: https://supabase.com/dashboard/project/xcihhnfcitjrwbynxmka/sql${NC}"
|
|
327
|
+
;;
|
|
328
|
+
|
|
329
|
+
sites)
|
|
330
|
+
echo -e "${BLUE}Listing all documentation sites${NC}"
|
|
331
|
+
generate_sites_sql
|
|
332
|
+
echo -e "${YELLOW}Copy and run the SQL above in Supabase SQL Editor${NC}"
|
|
333
|
+
echo -e "${YELLOW}Dashboard: https://supabase.com/dashboard/project/xcihhnfcitjrwbynxmka/sql${NC}"
|
|
334
|
+
;;
|
|
335
|
+
|
|
336
|
+
sql)
|
|
337
|
+
echo -e "${BLUE}Generating all SQL templates${NC}"
|
|
338
|
+
echo "-- Example: List all sites"
|
|
339
|
+
generate_sites_sql
|
|
340
|
+
echo ""
|
|
341
|
+
echo "-- Example: Add user"
|
|
342
|
+
generate_add_sql "example-docs.vercel.app" "user@example.com"
|
|
343
|
+
echo ""
|
|
344
|
+
echo "-- Example: List users"
|
|
345
|
+
generate_list_sql "example-docs.vercel.app"
|
|
346
|
+
echo ""
|
|
347
|
+
echo "-- Example: Check user"
|
|
348
|
+
generate_check_sql "example-docs.vercel.app" "user@example.com"
|
|
349
|
+
echo ""
|
|
350
|
+
echo "-- Example: Remove user"
|
|
351
|
+
generate_remove_sql "example-docs.vercel.app" "user@example.com"
|
|
352
|
+
;;
|
|
353
|
+
|
|
354
|
+
*)
|
|
355
|
+
show_help
|
|
356
|
+
;;
|
|
357
|
+
esac
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Example users file for bulk user additions
|
|
2
|
+
# One email per line
|
|
3
|
+
# Lines starting with # are ignored
|
|
4
|
+
# Empty lines are ignored
|
|
5
|
+
|
|
6
|
+
# Example users:
|
|
7
|
+
john@example.com
|
|
8
|
+
jane@example.com
|
|
9
|
+
admin@mycompany.com
|
|
10
|
+
|
|
11
|
+
# Real users for WRU project:
|
|
12
|
+
# pmorgan@wru.cymru
|
|
13
|
+
# clive@hyperforma.co.uk
|
|
14
|
+
# robbie.macintosh@marbledropper.com
|
|
15
|
+
# lindsay@knowcode.tech
|