nobalmako 1.0.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/README.md +112 -0
- package/components.json +22 -0
- package/dist/nobalmako.js +272 -0
- package/drizzle/0000_pink_spiral.sql +126 -0
- package/drizzle/meta/0000_snapshot.json +1027 -0
- package/drizzle/meta/_journal.json +13 -0
- package/drizzle.config.ts +10 -0
- package/eslint.config.mjs +18 -0
- package/next.config.ts +7 -0
- package/package.json +80 -0
- package/postcss.config.mjs +7 -0
- package/public/file.svg +1 -0
- package/public/globe.svg +1 -0
- package/public/next.svg +1 -0
- package/public/vercel.svg +1 -0
- package/public/window.svg +1 -0
- package/server/index.ts +118 -0
- package/src/app/api/api-keys/[id]/route.ts +147 -0
- package/src/app/api/api-keys/route.ts +151 -0
- package/src/app/api/audit-logs/route.ts +84 -0
- package/src/app/api/auth/forgot-password/route.ts +47 -0
- package/src/app/api/auth/login/route.ts +99 -0
- package/src/app/api/auth/logout/route.ts +15 -0
- package/src/app/api/auth/me/route.ts +23 -0
- package/src/app/api/auth/mfa/setup/route.ts +33 -0
- package/src/app/api/auth/mfa/verify/route.ts +45 -0
- package/src/app/api/auth/register/route.ts +140 -0
- package/src/app/api/auth/reset-password/route.ts +52 -0
- package/src/app/api/auth/update/route.ts +71 -0
- package/src/app/api/auth/verify/route.ts +39 -0
- package/src/app/api/environments/route.ts +227 -0
- package/src/app/api/team-members/route.ts +385 -0
- package/src/app/api/teams/route.ts +217 -0
- package/src/app/api/variable-history/route.ts +218 -0
- package/src/app/api/variables/route.ts +476 -0
- package/src/app/api/webhooks/route.ts +77 -0
- package/src/app/api-keys/APIKeysClient.tsx +316 -0
- package/src/app/api-keys/page.tsx +10 -0
- package/src/app/api-reference/page.tsx +324 -0
- package/src/app/audit-log/AuditLogClient.tsx +229 -0
- package/src/app/audit-log/page.tsx +10 -0
- package/src/app/auth/forgot-password/page.tsx +121 -0
- package/src/app/auth/login/LoginForm.tsx +145 -0
- package/src/app/auth/login/page.tsx +11 -0
- package/src/app/auth/register/RegisterForm.tsx +156 -0
- package/src/app/auth/register/page.tsx +16 -0
- package/src/app/auth/reset-password/page.tsx +160 -0
- package/src/app/dashboard/DashboardClient.tsx +219 -0
- package/src/app/dashboard/page.tsx +11 -0
- package/src/app/docs/page.tsx +251 -0
- package/src/app/favicon.ico +0 -0
- package/src/app/globals.css +123 -0
- package/src/app/layout.tsx +35 -0
- package/src/app/page.tsx +231 -0
- package/src/app/profile/ProfileClient.tsx +230 -0
- package/src/app/profile/page.tsx +10 -0
- package/src/app/project/[id]/ProjectDetailsClient.tsx +512 -0
- package/src/app/project/[id]/page.tsx +17 -0
- package/src/bin/nobalmako.ts +341 -0
- package/src/components/ApiKeysManager.tsx +529 -0
- package/src/components/AppLayout.tsx +193 -0
- package/src/components/BulkActions.tsx +138 -0
- package/src/components/CreateEnvironmentDialog.tsx +207 -0
- package/src/components/CreateTeamDialog.tsx +174 -0
- package/src/components/CreateVariableDialog.tsx +311 -0
- package/src/components/DeleteEnvironmentDialog.tsx +104 -0
- package/src/components/DeleteTeamDialog.tsx +112 -0
- package/src/components/DeleteVariableDialog.tsx +103 -0
- package/src/components/EditEnvironmentDialog.tsx +202 -0
- package/src/components/EditMemberDialog.tsx +143 -0
- package/src/components/EditTeamDialog.tsx +178 -0
- package/src/components/EditVariableDialog.tsx +231 -0
- package/src/components/ImportVariablesDialog.tsx +347 -0
- package/src/components/InviteMemberDialog.tsx +191 -0
- package/src/components/LeaveProjectDialog.tsx +111 -0
- package/src/components/MFASettings.tsx +136 -0
- package/src/components/ProjectDiff.tsx +123 -0
- package/src/components/Providers.tsx +24 -0
- package/src/components/RemoveMemberDialog.tsx +112 -0
- package/src/components/SearchDialog.tsx +276 -0
- package/src/components/SecurityOverview.tsx +92 -0
- package/src/components/TeamMembersManager.tsx +103 -0
- package/src/components/VariableHistoryDialog.tsx +265 -0
- package/src/components/WebhooksManager.tsx +169 -0
- package/src/components/ui/alert-dialog.tsx +160 -0
- package/src/components/ui/alert.tsx +59 -0
- package/src/components/ui/avatar.tsx +53 -0
- package/src/components/ui/badge.tsx +46 -0
- package/src/components/ui/button.tsx +62 -0
- package/src/components/ui/card.tsx +92 -0
- package/src/components/ui/checkbox.tsx +32 -0
- package/src/components/ui/dialog.tsx +143 -0
- package/src/components/ui/dropdown-menu.tsx +257 -0
- package/src/components/ui/input.tsx +21 -0
- package/src/components/ui/label.tsx +24 -0
- package/src/components/ui/select.tsx +190 -0
- package/src/components/ui/separator.tsx +28 -0
- package/src/components/ui/sonner.tsx +37 -0
- package/src/components/ui/switch.tsx +31 -0
- package/src/components/ui/table.tsx +117 -0
- package/src/components/ui/tabs.tsx +66 -0
- package/src/components/ui/textarea.tsx +18 -0
- package/src/hooks/use-api-keys.ts +95 -0
- package/src/hooks/use-audit-logs.ts +58 -0
- package/src/hooks/use-auth.tsx +121 -0
- package/src/hooks/use-environments.ts +33 -0
- package/src/hooks/use-project-permissions.ts +49 -0
- package/src/hooks/use-team-members.ts +30 -0
- package/src/hooks/use-teams.ts +33 -0
- package/src/hooks/use-variables.ts +38 -0
- package/src/lib/audit.ts +36 -0
- package/src/lib/auth.ts +108 -0
- package/src/lib/crypto.ts +39 -0
- package/src/lib/db.ts +15 -0
- package/src/lib/dynamic-providers.ts +19 -0
- package/src/lib/email.ts +110 -0
- package/src/lib/mail.ts +51 -0
- package/src/lib/permissions.ts +51 -0
- package/src/lib/schema.ts +240 -0
- package/src/lib/seed.ts +107 -0
- package/src/lib/utils.ts +6 -0
- package/src/lib/webhooks.ts +42 -0
- package/tsconfig.json +34 -0
package/src/lib/seed.ts
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import 'dotenv/config'
|
|
2
|
+
import { db } from './db'
|
|
3
|
+
import { users, teams, environments, environmentVariables, teamMembers } from './schema'
|
|
4
|
+
import bcrypt from 'bcryptjs'
|
|
5
|
+
import { encrypt } from './crypto'
|
|
6
|
+
|
|
7
|
+
async function seed() {
|
|
8
|
+
console.log('🌱 Seeding database...')
|
|
9
|
+
|
|
10
|
+
try {
|
|
11
|
+
// Clear existing data in correct order
|
|
12
|
+
console.log('Cleaning up existing data...')
|
|
13
|
+
await db.delete(teamMembers)
|
|
14
|
+
await db.delete(environmentVariables)
|
|
15
|
+
await db.delete(environments)
|
|
16
|
+
await db.delete(teams)
|
|
17
|
+
await db.delete(users)
|
|
18
|
+
|
|
19
|
+
// Create users
|
|
20
|
+
const hashedPassword = await bcrypt.hash('password123', 10)
|
|
21
|
+
|
|
22
|
+
console.log('Creating users...')
|
|
23
|
+
const [ownerUser] = await db.insert(users).values({
|
|
24
|
+
email: 'owner@nobalmako.com',
|
|
25
|
+
name: 'Owner User',
|
|
26
|
+
password: hashedPassword,
|
|
27
|
+
}).returning()
|
|
28
|
+
|
|
29
|
+
const [adminUser] = await db.insert(users).values({
|
|
30
|
+
email: 'admin@nobalmako.com',
|
|
31
|
+
name: 'Admin User',
|
|
32
|
+
password: hashedPassword,
|
|
33
|
+
}).returning()
|
|
34
|
+
|
|
35
|
+
const [devUser] = await db.insert(users).values({
|
|
36
|
+
email: 'dev@nobalmako.com',
|
|
37
|
+
name: 'Developer User',
|
|
38
|
+
password: hashedPassword,
|
|
39
|
+
}).returning()
|
|
40
|
+
|
|
41
|
+
const [viewerUser] = await db.insert(users).values({
|
|
42
|
+
email: 'viewer@nobalmako.com',
|
|
43
|
+
name: 'Viewer User',
|
|
44
|
+
password: hashedPassword,
|
|
45
|
+
}).returning()
|
|
46
|
+
|
|
47
|
+
// Create a demo project (team)
|
|
48
|
+
console.log('Creating project...')
|
|
49
|
+
const [project] = await db.insert(teams).values({
|
|
50
|
+
name: 'SecureApp V1',
|
|
51
|
+
description: 'Main production application for the company.',
|
|
52
|
+
ownerId: ownerUser.id,
|
|
53
|
+
}).returning()
|
|
54
|
+
|
|
55
|
+
// Assign team members with different roles
|
|
56
|
+
console.log('Assigning roles...')
|
|
57
|
+
await db.insert(teamMembers).values([
|
|
58
|
+
{ teamId: project.id, userId: adminUser.id, role: 'admin' },
|
|
59
|
+
{ teamId: project.id, userId: devUser.id, role: 'developer' },
|
|
60
|
+
{ teamId: project.id, userId: viewerUser.id, role: 'viewer' },
|
|
61
|
+
{ teamId: project.id, userId: ownerUser.id, role: 'owner' },
|
|
62
|
+
])
|
|
63
|
+
|
|
64
|
+
// Create environments
|
|
65
|
+
console.log('Creating environments...')
|
|
66
|
+
const [prodEnv] = await db.insert(environments).values({
|
|
67
|
+
name: 'Production',
|
|
68
|
+
teamId: project.id,
|
|
69
|
+
isDefault: true,
|
|
70
|
+
color: '#ef4444' // Red for prod
|
|
71
|
+
}).returning()
|
|
72
|
+
|
|
73
|
+
const [stagingEnv] = await db.insert(environments).values({
|
|
74
|
+
name: 'Staging',
|
|
75
|
+
teamId: project.id,
|
|
76
|
+
color: '#f59e0b' // Amber for staging
|
|
77
|
+
}).returning()
|
|
78
|
+
|
|
79
|
+
// Add some variables
|
|
80
|
+
console.log('Adding environment variables...')
|
|
81
|
+
const variables = [
|
|
82
|
+
{ key: 'DATABASE_URL', value: 'postgresql://prod-db.example.com/app', environmentId: prodEnv.id },
|
|
83
|
+
{ key: 'API_KEY', value: 'sk_prod_51Hj6l8V2', environmentId: prodEnv.id },
|
|
84
|
+
{ key: 'DATABASE_URL', value: 'postgresql://staging-db.example.com/app', environmentId: stagingEnv.id },
|
|
85
|
+
{ key: 'API_KEY', value: 'sk_test_90Kl2mP1', environmentId: stagingEnv.id },
|
|
86
|
+
]
|
|
87
|
+
|
|
88
|
+
for (const v of variables) {
|
|
89
|
+
await db.insert(environmentVariables).values({
|
|
90
|
+
key: v.key,
|
|
91
|
+
value: encrypt(v.value),
|
|
92
|
+
environmentId: v.environmentId,
|
|
93
|
+
teamId: project.id,
|
|
94
|
+
createdBy: ownerUser.id,
|
|
95
|
+
})
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
console.log('✅ Seed successful!')
|
|
99
|
+
console.log('Admin Email: admin@nobalmako.com')
|
|
100
|
+
console.log('Password: password123')
|
|
101
|
+
} catch (error) {
|
|
102
|
+
console.error('❌ Seed failed:', error)
|
|
103
|
+
process.exit(1)
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
seed()
|
package/src/lib/utils.ts
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { db } from '@/lib/db';
|
|
2
|
+
import { webhooks } from '@/lib/schema';
|
|
3
|
+
import { eq } from 'drizzle-orm';
|
|
4
|
+
import crypto from 'crypto';
|
|
5
|
+
|
|
6
|
+
export async function triggerWebhook(teamId: string, event: string, payload: any) {
|
|
7
|
+
try {
|
|
8
|
+
const results = await db.select().from(webhooks).where(eq(webhooks.teamId, teamId));
|
|
9
|
+
|
|
10
|
+
for (const hook of results) {
|
|
11
|
+
if (!hook.events?.includes(event)) continue;
|
|
12
|
+
|
|
13
|
+
const body = JSON.stringify({
|
|
14
|
+
event,
|
|
15
|
+
timestamp: new Date().toISOString(),
|
|
16
|
+
data: payload
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
const headers: Record<string, string> = {
|
|
20
|
+
'Content-Type': 'application/json',
|
|
21
|
+
'User-Agent': 'Nobalmako-Webhook/1.0',
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
if (hook.secret) {
|
|
25
|
+
const signature = crypto
|
|
26
|
+
.createHmac('sha256', hook.secret)
|
|
27
|
+
.update(body)
|
|
28
|
+
.digest('hex');
|
|
29
|
+
headers['X-Nobalmako-Signature'] = signature;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// Fire and forget (don't await to avoid slowing down main API response)
|
|
33
|
+
fetch(hook.url, {
|
|
34
|
+
method: 'POST',
|
|
35
|
+
headers,
|
|
36
|
+
body,
|
|
37
|
+
}).catch(err => console.error(`Webhook failed for ${hook.url}:`, err));
|
|
38
|
+
}
|
|
39
|
+
} catch (error) {
|
|
40
|
+
console.error('Error triggering webhooks:', error);
|
|
41
|
+
}
|
|
42
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2017",
|
|
4
|
+
"lib": ["dom", "dom.iterable", "esnext"],
|
|
5
|
+
"allowJs": true,
|
|
6
|
+
"skipLibCheck": true,
|
|
7
|
+
"strict": true,
|
|
8
|
+
"noEmit": true,
|
|
9
|
+
"esModuleInterop": true,
|
|
10
|
+
"module": "esnext",
|
|
11
|
+
"moduleResolution": "bundler",
|
|
12
|
+
"resolveJsonModule": true,
|
|
13
|
+
"isolatedModules": true,
|
|
14
|
+
"jsx": "react-jsx",
|
|
15
|
+
"incremental": true,
|
|
16
|
+
"plugins": [
|
|
17
|
+
{
|
|
18
|
+
"name": "next"
|
|
19
|
+
}
|
|
20
|
+
],
|
|
21
|
+
"paths": {
|
|
22
|
+
"@/*": ["./src/*"]
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"include": [
|
|
26
|
+
"next-env.d.ts",
|
|
27
|
+
"**/*.ts",
|
|
28
|
+
"**/*.tsx",
|
|
29
|
+
".next/types/**/*.ts",
|
|
30
|
+
".next/dev/types/**/*.ts",
|
|
31
|
+
"**/*.mts"
|
|
32
|
+
],
|
|
33
|
+
"exclude": ["node_modules", "server"]
|
|
34
|
+
}
|