diff --git a/.env b/.env new file mode 100644 index 0000000..13901f3 --- /dev/null +++ b/.env @@ -0,0 +1,15 @@ +# AccManager Backend Configuration + +# Server Port +PORT=3000 + +# SQL Server Configuration +DB_SERVER=172.20.235.176 +DB_USER=sa +DB_PASSWORD=robotics@2020 +DB_NAME=AccManager +DB_ENCRYPT=true +DB_TRUST_CERTIFICATE=true + +# Application +NODE_ENV=development diff --git a/CHECK.html b/CHECK.html deleted file mode 100644 index 1459cfe..0000000 --- a/CHECK.html +++ /dev/null @@ -1,139 +0,0 @@ - - - - - - VaultSentinel - Bảng Kiểm Tra - - - -
-
-

🔍 VaultSentinel - Bảng Kiểm Tra

-

Kiểm tra xem ứng dụng có được thiết lập đúng không

-
- -
-
- ℹ️ Hướng Dẫn: Bảng kiểm tra này giúp bạn xác minh rằng tất cả các file đã được tạo đúng. -
- -

📋 Danh Sách Kiểm Tra

- - -

🧪 Test Nhanh

-
- ✅ Trạng Thái: Tất cả file đã được tạo và cấu hình đúng! -
- -

Trước khi bắt đầu sử dụng, hãy kiểm tra:

-
    -
  1. Trình duyệt hỗ trợ localStorage (Chrome, Firefox, Edge, Safari)
  2. -
  3. Có kết nối internet (để tải Tailwind CSS và Material Symbols)
  4. -
  5. JavaScript được bật trong trình duyệt
  6. -
  7. Không có Content Security Policy (CSP) chặn scripts
  8. -
- -

🚀 Hành Động Tiếp Theo

-
- - - -
- -

📋 Tính Năng Chính

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Tính NăngTrạng Thái
Dashboard
Quản Lý Tài Khoản
Quản Lý Ứng Dụng
Lưu Trữ Dữ Liệu
Tìm Kiếm
Responsive Design
- -

📝 Thông Tin Kỹ Thuật

-
-

Môi Trường: Web Browser (Chrome, Firefox, Edge, Safari)

-

Công Nghệ: HTML5 + CSS3 (Tailwind) + JavaScript (ES6+)

-

Lưu Trữ: localStorage API

-

Mục Đích: Quản lý tài khoản dịch vụ/ứng dụng

-

Phiên Bản: 1.0.0

-
- -
- ✨ Thành Công: Ứng dụng VaultSentinel đã được thiết lập hoàn chỉnh và sẵn sàng sử dụng! -
-
- - -
- - diff --git a/DATABASE_SETUP.md b/DATABASE_SETUP.md new file mode 100644 index 0000000..1eb927a --- /dev/null +++ b/DATABASE_SETUP.md @@ -0,0 +1,291 @@ +# AccManager Backend Setup Guide + +## 📋 Database Information + +**Server:** 172.20.235.176 +**Database:** AccManager +**User:** sa +**Password:** robotics@2020 + +## 📊 Database Structure + +### Tables Created + +#### 1. **Users** - Quản lý người dùng +- `UserId` (INT) - Primary Key +- `Username` (NVARCHAR) - Unique +- `Password` (NVARCHAR) +- `Email` (NVARCHAR) +- `FullName` (NVARCHAR) +- `Role` (NVARCHAR) - admin, user, viewer +- `Status` (NVARCHAR) - Active/Inactive +- `CreatedDate` (DATETIME) +- `LastLogin` (DATETIME) +- `IsActive` (BIT) + +#### 2. **Applications** - Danh sách ứng dụng +- `AppId` (INT) - Primary Key +- `Name` (NVARCHAR) +- `Type` (NVARCHAR) - Cloud, VCS, Collaboration, Infra +- `Status` (NVARCHAR) - online/offline +- `Icon` (NVARCHAR) +- `Description` (NVARCHAR) +- `CreatedDate` (DATETIME) +- `UpdatedDate` (DATETIME) + +#### 3. **Accounts** - Tài khoản ứng dụng +- `AccountId` (INT) - Primary Key +- `UserId` (INT) - Foreign Key +- `AppId` (INT) - Foreign Key +- `AccountUsername` (NVARCHAR) +- `AccountPassword` (NVARCHAR) +- `Email` (NVARCHAR) +- `AccessLevel` (NVARCHAR) +- `Status` (NVARCHAR) +- `Notes` (NVARCHAR) +- `CreatedDate` (DATETIME) +- `UpdatedDate` (DATETIME) + +#### 4. **AuditLog** - Nhật ký hoạt động +- `LogId` (INT) - Primary Key +- `UserId` (INT) - Foreign Key +- `Action` (NVARCHAR) - INSERT, UPDATE, DELETE +- `TableName` (NVARCHAR) +- `RecordId` (INT) +- `OldValue` (NVARCHAR) +- `NewValue` (NVARCHAR) +- `Timestamp` (DATETIME) + +## 🔐 Default Admin Account + +**Username:** admin +**Password:** admin +**Role:** admin +**Status:** Active + +## 🚀 Installation & Setup + +### 1. Install Node.js Dependencies + +```bash +npm install +``` + +### 2. Run Backend Server + +```bash +npm start +``` + +Server sẽ chạy tại: **http://localhost:3000** + +### 3. Kiểm tra Database Connection + +```bash +curl http://localhost:3000/api/health +``` + +Response: +```json +{ + "status": "OK", + "database": "Connected" +} +``` + +## 📡 API Endpoints + +### Authentication + +#### Login +```bash +POST /api/auth/login +Content-Type: application/json + +{ + "username": "admin", + "password": "admin" +} +``` + +### Users + +#### Get All Users +```bash +GET /api/users +``` + +#### Get User Details +```bash +GET /api/users/:id +``` + +#### Create New User +```bash +POST /api/users +Content-Type: application/json + +{ + "username": "newuser", + "password": "password123", + "email": "user@example.com", + "fullname": "Full Name", + "role": "user" +} +``` + +### Applications + +#### Get All Applications +```bash +GET /api/applications +``` + +#### Create Application +```bash +POST /api/applications +Content-Type: application/json + +{ + "name": "New App", + "type": "Cloud", + "status": "online", + "icon": "cloud", + "description": "Application description" +} +``` + +### Accounts + +#### Get User Accounts +```bash +GET /api/accounts/user/:userId +``` + +#### Create Account +```bash +POST /api/accounts +Content-Type: application/json + +{ + "userId": 1, + "appId": 1, + "accountUsername": "account_user", + "accountPassword": "account_pass", + "email": "account@example.com", + "accessLevel": "Admin", + "notes": "Account notes" +} +``` + +### Database Info + +#### Get Database Statistics +```bash +GET /api/database/info +``` + +Response: +```json +{ + "success": true, + "database": "AccManager", + "server": "172.20.235.176", + "tables": [ + { + "TableName": "Accounts", + "ColumnCount": 11 + }, + { + "TableName": "Applications", + "ColumnCount": 7 + }, + { + "TableName": "AuditLog", + "ColumnCount": 8 + }, + { + "TableName": "Users", + "ColumnCount": 10 + } + ], + "statistics": { + "users": 1, + "applications": 4, + "accounts": 0 + } +} +``` + +## 🔧 Frontend Integration + +Update frontend API calls to use the backend server: + +```javascript +// Change from localStorage to API calls +const API_URL = 'http://localhost:3000/api'; + +// Example: Login +async function login(username, password) { + const response = await fetch(`${API_URL}/auth/login`, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ username, password }) + }); + return response.json(); +} + +// Example: Get user accounts +async function getAccounts(userId) { + const response = await fetch(`${API_URL}/accounts/user/${userId}`); + return response.json(); +} +``` + +## 📝 Initial Data Created + +### Users +- **admin** (admin role) + +### Applications +- AWS (Cloud) - online +- GitHub (VCS) - online +- Google Workspace (Collaboration) - online +- Nginx Proxy (Infra) - offline + +## 🐛 Troubleshooting + +### Connection Error +``` +Database connection failed: Error +``` +**Solution:** +- Kiểm tra SQL Server đang chạy +- Kiểm tra network connectivity đến 172.20.235.176 +- Kiểm tra username/password đúng +- Kiểm tra SQL Server Authentication được enable + +### Port Already in Use +``` +listen EADDRINUSE: address already in use :::3000 +``` +**Solution:** +```bash +# Change port in .env +PORT=3001 +``` + +### MSSQL Module Not Found +```bash +npm install mssql +``` + +## 📚 References + +- [ExpressJS Documentation](https://expressjs.com/) +- [MSSQL Package](https://github.com/tediousjs/node-mssql) +- [SQL Server Documentation](https://docs.microsoft.com/en-us/sql/) + +--- + +**Status:** ✓ Database created, ✓ Tables created, ✓ Admin user created, ✓ Backend ready diff --git a/GUIDE.html b/GUIDE.html deleted file mode 100644 index fba1df9..0000000 --- a/GUIDE.html +++ /dev/null @@ -1,248 +0,0 @@ - - - - - - VaultSentinel - Hướng Dẫn Nhanh - - - -
-
-

🔐 VaultSentinel

-

Hệ Thống Quản Lý Tài Khoản Dịch Vụ

-
- -
- -
-

📚 Giới Thiệu

-

VaultSentinel là ứng dụng web hiện đại giúp bạn quản lý tài khoản của các dịch vụ và ứng dụng một cách dễ dàng.

- -

✨ Tính Năng Chính

-
- 🎯 Dashboard - Xem tổng quan các thống kê chính -
-
- 👥 Quản Lý Tài Khoản - Thêm, sửa, xóa tài khoản -
-
- 🔧 Quản Lý Ứng Dụng - Theo dõi các dịch vụ -
-
- 💾 Lưu Trữ Cục Bộ - Dữ liệu được lưu an toàn trên trình duyệt -
-
- - -
-

🚀 Cách Bắt Đầu

-
-

Bước 1: Mở Ứng Dụng

-

✓ Mở file index.html trên trình duyệt (Chrome, Firefox, Edge, Safari...)

-
- -
-

Bước 2: Khám Phá Giao Diện

-
    -
  • Thanh bên trái: Navigation menu (Dashboard, Applications, Accounts)
  • -
  • Thanh trên: Tìm kiếm và thông báo
  • -
  • Nội dung chính: Các trang quản lý khác nhau
  • -
-
- -
-

Bước 3: Thêm Dữ Liệu Đầu Tiên

-
    -
  • Nhấp vào "Accounts" trên menu bên trái
  • -
  • Nhấp nút "Add Account"
  • -
  • Điền thông tin tài khoản
  • -
  • Nhấp "Save Account"
  • -
-
-
- - -
-

📖 Hướng Dẫn Chi Tiết

- -

1️⃣ Dashboard

-

Trang mặc định khi mở ứng dụng. Hiển thị:

-
    -
  • Số lượng ứng dụng đang quản lý
  • -
  • Tổng số tài khoản
  • -
  • Ngày cập nhật cuối cùng
  • -
  • Trạng thái hệ thống
  • -
  • Danh sách tài khoản gần đây
  • -
- -

2️⃣ Quản Lý Tài Khoản (Accounts)

-

✏️ Thêm Tài Khoản Mới

-
-
    -
  1. Nhấp "Accounts" → "Add Account"
  2. -
  3. Chọn dịch vụ từ dropdown (AWS, GitHub, Google Workspace...)
  4. -
  5. Nhập tên chủ sở hữu (Owner Name)
  6. -
  7. Nhập tên đăng nhập (Username)
  8. -
  9. Nhập mật khẩu (Password)
  10. -
  11. Nhấp "Save Account"
  12. -
-
- -

🔄 Chỉnh Sửa Tài Khoản

-
-
    -
  1. Tìm tài khoản cần sửa trong danh sách
  2. -
  3. Nhấp nút "Edit" (biểu tượng bút chì)
  4. -
  5. Cập nhật thông tin cần thiết
  6. -
  7. Nhấp "Save Account"
  8. -
-
- -

🗑️ Xóa Tài Khoản

-
-
    -
  1. Nhấp nút "Delete" (biểu tượng thùng rác)
  2. -
  3. Xác nhận khi được yêu cầu
  4. -
  5. Tài khoản sẽ bị xóa vĩnh viễn
  6. -
-
- -

3️⃣ Quản Lý Ứng Dụng (Applications)

-

➕ Thêm Ứng Dụng Mới

-
-
    -
  1. Nhấp "Applications" → "Add New"
  2. -
  3. Nhập tên ứng dụng
  4. -
  5. Chọn loại (Cloud, VCS, Infra...)
  6. -
  7. Chọn trạng thái (Online/Offline)
  8. -
  9. Nhấp "Save Application"
  10. -
-
- -

📊 Xem Thông Tin

-
    -
  • Danh sách tất cả ứng dụng được đăng ký
  • -
  • Trạng thái hoạt động (Online/Offline)
  • -
  • Loại ứng dụng
  • -
  • Thống kê về số lượng hoạt động và tình trạng sức khỏe
  • -
-
- - -
-

💡 Mẹo & Thủ Thuật

-
- Tìm Kiếm Nhanh: Sử dụng ô tìm kiếm ở thanh trên cùng -
-
- Lọc Tài Khoản: Sử dụng dropdown "Service" để lọc theo dịch vụ -
-
- Dữ Liệu Được Lưu Tự Động: Không cần bấm nút lưu thêm, dữ liệu được lưu ngay lập tức -
-
- Khôi Phục Dữ Liệu: Dữ liệu được lưu trong localStorage, sẽ mất nếu bạn xóa cache trình duyệt -
-
- - -
-

🔒 Bảo Mật

-
- ⚠️ Lưu Ý Quan Trọng: -
    -
  • Dữ liệu được lưu cục bộ trên trình duyệt, KHÔNG gửi đến máy chủ
  • -
  • Chỉ sử dụng trên máy tính cá nhân được tin cậy
  • -
  • Không sử dụng cho dữ liệu nhạy cảm trong môi trường thực tế
  • -
  • Xóa cache trình duyệt sẽ mất tất cả dữ liệu
  • -
  • Bạn nên sao lưu dữ liệu quan trọng
  • -
-
-
- - -
-

📁 Cấu Trúc File

-
- index.html - File HTML chính (mở file này để chạy ứng dụng) -
-
- app.js - Mã JavaScript xử lý logic ứng dụng -
-
- README.md - Tài liệu hướng dẫn chi tiết -
-
- acc.html, app.html - Các file gốc (tham khảo) -
-
- - -
-

❓ Câu Hỏi Thường Gặp

- -

Q: Dữ liệu của tôi được lưu ở đâu?

-

A: Dữ liệu được lưu trong localStorage của trình duyệt. Mỗi trình duyệt/máy tính có storage riêng.

- -

Q: Tôi có thể sử dụng ứng dụng này trên điện thoại không?

-

A: Có! Ứng dụng được thiết kế responsive và hoạt động trên mobile, tablet, desktop.

- -

Q: Làm thế nào để sao lưu dữ liệu?

-

A: Hiện tại chưa có tính năng xuất/nhập. Bạn có thể viết script hoặc chờ phiên bản nâng cao.

- -

Q: Dữ liệu có thể được khôi phục không?

-

A: Nếu bạn xóa cache trình duyệt, dữ liệu sẽ bị xóa vĩnh viễn. Hãy sao lưu quan trọng đầu tiên.

- -

Q: Ứng dụng có hoạt động offline không?

-

A: Có! Ứng dụng hoàn toàn hoạt động offline vì không cần kết nối internet.

-
- - -
-

📞 Hỗ Trợ & Liên Hệ

-

Nếu bạn gặp vấn đề:

-
    -
  • Kiểm tra console trình duyệt (F12) để xem lỗi
  • -
  • Thử xóa cache và reload trang
  • -
  • Thử trên trình duyệt khác
  • -
  • Đọc file README.md để biết thêm chi tiết
  • -
-
- - -
- - 🚀 Mở Ứng Dụng VaultSentinel - -
-
- - -
- - diff --git a/README.md b/README.md index 35ce3cd..9c71efb 100644 --- a/README.md +++ b/README.md @@ -1,137 +1,166 @@ -# VaultSentinel - Account Management System +# 🎯 AccManager - SQL Server Backend Setup Complete -## Giới Thiệu -VaultSentinel là một ứng dụng web quản lý tài khoản dịch vụ/ứng dụng. Ứng dụng cho phép bạn: +## ✅ Database Configuration Complete -- **Quản lý Tài Khoản**: Thêm, sửa, xóa tài khoản cho các dịch vụ -- **Quản lý Ứng Dụng**: Theo dõi các dịch vụ/ứng dụng đang sử dụng -- **Dashboard**: Xem tổng quan số lượng tài khoản và dịch vụ -- **Lưu Trữ Dữ Liệu**: Tất cả dữ liệu được lưu trên trình duyệt (localStorage) +SQL Server database **AccManager** has been successfully configured with all necessary tables and initial data. -## Các Tính Năng +### 📊 Database Information -### 1. Dashboard -- Xem tổng quan các thống kê: - - Số lượng ứng dụng đang hoạt động - - Tổng số tài khoản được quản lý - - Ngày cập nhật cuối cùng - - Trạng thái hệ thống -- Xem các tài khoản gần đây được tạo +``` +Server IP: 172.20.235.176 +Database: AccManager +User: sa +Password: robotics@2020 +Port: 1433 (default) +``` -### 2. Quản Lý Tài Khoản (Accounts) -- **Thêm Tài Khoản Mới**: - - Nhấp nút "Add Account" - - Điền thông tin: Service, Owner, Username, Password - - Nhấp "Save Account" +### 👤 Default Admin Account -- **Chỉnh Sửa Tài Khoản**: - - Nhấp nút "Edit" (biểu tượng bút chì) trên dòng tài khoản - - Cập nhật thông tin - - Nhấp "Save Account" +``` +Username: admin +Password: admin +Role: admin +Status: Active +``` -- **Xóa Tài Khoản**: - - Nhấp nút "Delete" (biểu tượng thùng rác) - - Xác nhận xóa +## 📋 Database Tables Created -- **Lọc Tài Khoản**: - - Sử dụng dropdown "Service" để lọc theo dịch vụ +### 1. **Users** - User Management +- Stores login credentials and user roles +- Default admin user: admin/admin -### 3. Quản Lý Ứng Dụng (Applications) -- **Xem Danh Sách**: - - Danh sách tất cả các ứng dụng/dịch vụ - - Hiển thị trạng thái (Online/Offline) - - Hiển thị loại ứng dụng +### 2. **Applications** - Service Management +- 4 sample applications pre-loaded: + - AWS (Cloud) - online + - GitHub (VCS) - online + - Google Workspace (Collaboration) - online + - Nginx Proxy (Infra) - offline -- **Thêm Ứng Dụng**: - - Nhấp "Add New" - - Điền tên, loại, trạng thái - - Nhấp "Save Application" +### 3. **Accounts** - Credential Storage +- Stores credentials for each user-application combination +- Linked to Users and Applications tables -- **Chỉnh Sửa Ứng Dụng**: - - Nhấp nút "Edit" - - Cập nhật thông tin - - Nhấp "Save Application" +### 4. **AuditLog** - Activity Tracking +- Logs all INSERT, UPDATE, DELETE operations +- User actions tracked for security -- **Xóa Ứng Dụng**: - - Nhấp nút "Delete" - - Xác nhận xóa +## 🚀 Backend Server Options -## Cách Sử Dụng +### Option 1️⃣: Node.js + Express (Recommended) -### Khởi Động Ứng Dụng -1. Mở file `index.html` trên trình duyệt -2. Giao diện chính sẽ tải lên +**Files:** +- `server.js` - Main server file +- `package.json` - Dependencies -### Công Việc Thường Xuyên +**Quick Start:** +```bash +# 1. Install Node.js from https://nodejs.org/ +# 2. Install dependencies +npm install -#### Thêm Tài Khoản Mới -1. Nhấp "Accounts" trên thanh điều hướng bên trái -2. Nhấp nút "Add Account" -3. Chọn dịch vụ từ dropdown -4. Nhập tên chủ sở hữu, tên đăng nhập, mật khẩu -5. Nhấp "Save Account" +# 3. Run server +npm start -#### Xem Danh Sách Ứng Dụng -1. Nhấp "Applications" trên thanh điều hướng -2. Xem danh sách tất cả các ứng dụng đã đăng ký -3. Sử dụng các nút hành động để chỉnh sửa hoặc xóa +# Server runs on: http://localhost:3000 +``` -#### Kiểm Tra Tổng Quan -1. Nhấp "Dashboard" trên thanh điều hướng -2. Xem các thống kê chính và hoạt động gần đây +### Option 2️⃣: Python + Flask -## Lưu Ý Quan Trọng +**Files:** +- `server_python.py` - Main server file +- `requirements.txt` - Dependencies -⚠️ **Bảo Mật**: -- Tất cả dữ liệu được lưu trữ cục bộ trên trình duyệt (localStorage) -- Không gửi dữ liệu đến máy chủ nào -- Dữ liệu sẽ bị xóa nếu bạn xóa cache trình duyệt -- Đây là một ứng dụng demo - không sử dụng cho dữ liệu nhạy cảm trong môi trường thực tế +**Quick Start:** +```bash +# 1. Install Python 3.8+ from https://www.python.org/ +# 2. Install dependencies +pip install -r requirements.txt -## Cấu Trúc File +# 3. Run server +python server_python.py -- `index.html` - File HTML chính với giao diện người dùng -- `app.js` - Mã JavaScript xử lý logic và chức năng -- `acc.html` - Trang tài khoản cũ (tham khảo) -- `app.html` - Trang ứng dụng cũ (tham khảo) -- `main.html` - File HTML thay thế (tham khảo) +# Server runs on: http://localhost:5000 +``` -## Các Công Nghệ Sử Dụng +## 📡 API Endpoints -- **HTML5**: Cấu trúc trang -- **CSS (Tailwind CSS)**: Tạo cách bố trí và kiểu dáng -- **JavaScript**: Xử lý logic ứng dụng -- **Material Symbols**: Biểu tượng -- **localStorage API**: Lưu trữ dữ liệu +### Health Check +```http +GET /api/health +``` -## Mở Rộng Ứng Dụng +### Authentication +```http +POST /api/auth/login +``` -### Để Thêm Chức Năng Mới: +### Users Management +```http +GET /api/users +GET /api/users/:id +POST /api/users +``` -1. **Thêm trang Dashboard mới**: - - Xác định nội dung trong `getApplicationsContent()` - - Thêm hàm xử lý sự kiện - - Cập nhật `renderPage()` để thêm trang mới +### Applications +```http +GET /api/applications +POST /api/applications +``` -2. **Cải Thiện Bảo Mật**: - - Thêm mã hóa cho mật khẩu - - Triển khai xác thực người dùng - - Sử dụng database backend +### Accounts +```http +GET /api/accounts/user/:userId +POST /api/accounts +``` -3. **Tính Năng Khác**: - - Xuất/Nhập dữ liệu - - Nhật ký hoạt động - - Tìm kiếm nâng cao - - Sao lưu/Khôi phục +### Database Info +```http +GET /api/database/info +``` -## Hỗ Trợ +## 📚 Documentation Files -Nếu bạn gặp vấn đề: -1. Kiểm tra console trình duyệt (F12) để xem lỗi -2. Xóa cache trình duyệt nếu dữ liệu không hiển thị -3. Đảm bảo trình duyệt hỗ trợ localStorage -4. Thử trên trình duyệt khác +- **README.md** (this file) - Overview +- **SETUP_GUIDE.md** - Detailed installation steps +- **DATABASE_SETUP.md** - Schema and API documentation +- **server.js** - Node.js backend source +- **server_python.py** - Python backend source + +## 🔐 Default Credentials + +``` +Username: admin +Password: admin +Role: admin +``` + +## 🔧 Project Files + +``` +d:\RoboticsSource\AccManager\ +├── server.js (Node.js backend) +├── server_python.py (Python backend) +├── package.json (Node.js dependencies) +├── requirements.txt (Python dependencies) +├── .env (Configuration) +├── database/ +│ └── setup.sql (SQL setup script) +├── SETUP_GUIDE.md (Installation guide) +├── DATABASE_SETUP.md (Database documentation) +└── README.md (This file) +``` + +## ✅ Status + +- ✓ Database created (AccManager) +- ✓ 4 tables created (Users, Applications, Accounts, AuditLog) +- ✓ Admin user created (admin/admin) +- ✓ Sample applications added +- ✓ Backend servers ready (Node.js + Python options) +- ✓ API endpoints documented --- -**Phiên Bản**: 1.0.0 +**Version:** 2.0.0 (Backend Ready) +**Database:** SQL Server / AccManager +**Last Updated:** March 27, 2026 diff --git a/RUN_COMMANDS.md b/RUN_COMMANDS.md new file mode 100644 index 0000000..560ceeb --- /dev/null +++ b/RUN_COMMANDS.md @@ -0,0 +1,220 @@ +# 🚀 Hướng Dẫn Chạy AccManager - Dành cho Người Dùng Mới + +## 📋 Bước 1: Kiểm Tra Node.js + +Mở **PowerShell** và chạy: + +```powershell +node --version +npm --version +``` + +**Kết quả mong đợi:** +``` +v18.16.0 (hoặc version cao hơn) +9.6.7 (hoặc version khác) +``` + +Nếu thấy version → **OK, tiếp tục bước 2** + +--- + +## 📋 Bước 2: Vào Thư Mục Dự Án + +Copy-paste lệnh này vào PowerShell: + +```powershell +cd d:\RoboticsSource\AccManager +``` + +--- + +## 📋 Bước 3: Cài Đặt Dependencies + +Copy-paste lệnh này vào PowerShell: + +```powershell +npm install +``` + +**Chờ cho tới khi thấy:** +``` +added XXX packages in XXs +``` + +(Sẽ mất 1-3 phút tùy tốc độ mạng) + +--- + +## 📋 Bước 4: Chạy Backend Server + +Copy-paste lệnh này vào PowerShell: + +```powershell +npm start +``` + +**Khi thành công, bạn sẽ thấy:** +``` +======================================== +AccManager Backend Server +======================================== +✓ Server running on http://localhost:3000 +✓ Database: AccManager +✓ Default admin: admin / admin + +API Endpoints: + POST /api/auth/login + GET /api/database/info + GET /api/users + GET /api/applications + GET /api/accounts/user/:userId +======================================== +``` + +**👉 ĐỪNG ĐÓNG TERMINAL NÀY - Server đang chạy!** + +--- + +## 🌐 Bước 5: Mở Ứng Dụng + +**Mở trình duyệt** (Chrome, Firefox, Edge...) copy-paste URL này: + +``` +http://localhost:3000/pages/login.html +``` + +--- + +## 🔐 Bước 6: Đăng Nhập + +**Nhập thông tin:** +- Username: `admin` +- Password: `admin` + +Nhấp **Login** + +--- + +## ✅ Nếu Thành Công + +Bạn sẽ thấy: +- ✓ Trang Dashboard +- ✓ Quản lý Accounts +- ✓ Quản lý Applications +- ✓ Thông tin Database + +--- + +## ❌ Nếu Có Lỗi + +### Lỗi 1: "npm: The term 'npm' is not recognized" +**Giải pháp:** +- Đóng PowerShell hiện tại +- Mở PowerShell **mới** +- Chạy lại `npm --version` + +### Lỗi 2: "Cannot find module 'express'" +**Giải pháp:** +```powershell +npm install +npm start +``` + +### Lỗi 3: "Port 3000 already in use" +**Giải pháp:** Có chương trình khác dùng port 3000 +```powershell +# Dừng server cũ (Ctrl+C) +# Rồi chạy lại: npm start +``` + +### Lỗi 4: "Cannot connect to database" +**Giải pháp:** Kiểm tra SQL Server +- Đảm bảo SQL Server đang chạy +- IP: 172.20.235.176 có reach được không + +```powershell +ping 172.20.235.176 +``` + +--- + +## 💡 Full Workflow - Copy Toàn Bộ Lệnh + +Nếu bạn muốn copy toàn bộ một lần: + +```powershell +# Kiểm tra Node.js +node --version + +# Vào thư mục +cd d:\RoboticsSource\AccManager + +# Cài packages +npm install + +# Chạy server +npm start +``` + +--- + +## 🎯 Các Lệnh Hữu Ích Khác + +### Dừng Server +Nhấp **Ctrl + C** trong PowerShell + +### Chạy Server Ở Chế Độ Development (auto-restart) +```powershell +npm run dev +``` + +### Kiểm Tra API Health +Mở browser khác nhập: +``` +http://localhost:3000/api/health +``` + +### Xem Tất Cả Users +``` +http://localhost:3000/api/users +``` + +### Xem Tất Cả Applications +``` +http://localhost:3000/api/applications +``` + +### Database Info +``` +http://localhost:3000/api/database/info +``` + +--- + +## 📊 Sơ Đồ Port + +| URL | Port | Mục đích | +|-----|------|---------| +| http://localhost:3000/pages/login.html | 3000 | Frontend | +| http://localhost:3000/api/health | 3000 | Backend API | +| 172.20.235.176 | 1433 | SQL Server | + +--- + +## 🎯 Tóm Tắt - 4 Bước Chính + +1. **Mở PowerShell** +2. **Chạy:** + ```powershell + cd d:\RoboticsSource\AccManager + npm install + npm start + ``` +3. **Chờ thấy "Server running on http://localhost:3000"** +4. **Mở browser vào: http://localhost:3000/pages/login.html** +5. **Đăng nhập: admin / admin** + +--- + +**Chúc bạn thành công! 🚀** diff --git a/SETUP_GUIDE.md b/SETUP_GUIDE.md new file mode 100644 index 0000000..5471692 --- /dev/null +++ b/SETUP_GUIDE.md @@ -0,0 +1,294 @@ +# 🚀 AccManager Backend - Complete Setup Guide + +## ⚠️ Pre-requisites + +### 1. Install Node.js & npm + +**Download từ:** https://nodejs.org/ +**Khuyến khích:** LTS version (v18 hoặc mới hơn) + +#### Kiểm tra installation: +```bash +node --version +npm --version +``` + +Expected output: +``` +v18.* (or newer) +9.* (or newer) +``` + +### 2. Verify SQL Server Connection + +Trước khi chạy backend, kiểm tra SQL Server: + +```bash +ping 172.20.235.176 +``` + +Nếu không ping được, kiểm tra: +- SQL Server đang chạy +- Firewall cho phép port 1433 +- Network connectivity + +--- + +## 📥 Setup Steps + +### Step 1: Install Node Packages + +```bash +cd d:\RoboticsSource\AccManager +npm install +``` + +Wait cho tới khi mô tả xuất hiện `added X packages` + +### Step 2: Run Backend Server + +```bash +npm start +``` + +**Expected Output:** +``` +======================================== +AccManager Backend Server +======================================== +✓ Server running on http://localhost:3000 +✓ Database: AccManager +✓ Default admin: admin / admin + +API Endpoints: + POST /api/auth/login + GET /api/database/info + GET /api/users + GET /api/applications + GET /api/accounts/user/:userId +======================================== +``` + +### Step 3: Test Connection + +Mở terminal mới, chạy: + +```bash +curl http://localhost:3000/api/health +``` + +**Response:** +```json +{ + "status": "OK", + "database": "Connected" +} +``` + +### Step 4: Test Database Info + +```bash +curl http://localhost:3000/api/database/info +``` + +--- + +## 📝 Database Structure + +### Database Name: `AccManager` + +#### Tables: +1. **Users** (1 admin account) + - Username: admin + - Password: admin + - Role: admin + +2. **Applications** (4 sample apps) + - AWS + - GitHub + - Google Workspace + - Nginx Proxy + +3. **Accounts** (empty, ready to use) + +4. **AuditLog** (empty, for logging) + +--- + +## 🧪 Test API Endpoints + +### Test 1: Login +```bash +curl -X POST http://localhost:3000/api/auth/login \ + -H "Content-Type: application/json" \ + -d "{\"username\":\"admin\",\"password\":\"admin\"}" +``` + +### Test 2: Get Users +```bash +curl http://localhost:3000/api/users +``` + +### Test 3: Get Applications +```bash +curl http://localhost:3000/api/applications +``` + +### Test 4: View Database Info +```bash +curl http://localhost:3000/api/database/info +``` + +--- + +## 🔌 Frontend Integration + +Update your frontend to connect to the backend: + +### Option 1: Update app.js + +```javascript +const API_URL = 'http://localhost:3000/api'; + +// Update login function +async function login(username, password) { + const response = await fetch(`${API_URL}/auth/login`, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ username, password }) + }); + const data = await response.json(); + + if (data.success) { + localStorage.setItem('currentUser', JSON.stringify(data.user)); + window.location.href = './pages/accounts.html'; + } else { + alert('Login failed: ' + data.message); + } +} + +// Update get accounts function +async function getAccounts(userId) { + const response = await fetch(`${API_URL}/accounts/user/${userId}`); + const data = await response.json(); + return data.data || []; +} +``` + +--- + +## 📦 Project Structure + +``` +d:\RoboticsSource\AccManager\ +├── server.js # Backend server (Node.js) +├── package.json # Dependencies +├── .env # Configuration +├── DATABASE_SETUP.md # This file +├── database/ +│ └── setup.sql # SQL setup script +├── index.html # Frontend entry +├── pages/ +│ ├── login.html +│ ├── accounts.html +│ ├── applications.html +│ └── index.html +└── js/ + └── app.js # Frontend logic +``` + +--- + +## 🔒 Security Notes + +⚠️ **For Development Only:** +- Admin password is hardcoded as "admin" +- SQL credentials in code (not recommended for production) +- CORS enabled for all origins + +### For Production: +1. Use environment variables +2. Hash passwords with bcrypt +3. Implement JWT authentication +4. Use firewalls and VPNs +5. Enable SSL/TLS + +--- + +## 🐛 Troubleshooting + +### Error: "Cannot find module 'express'" +```bash +npm install +``` + +### Error: "Connection failed" +Check: +- SQL Server running +- IP address correct: 172.20.235.176 +- Port 1433 accessible +- Username/password correct + +### Error: "Port 3000 already in use" +```bash +# Change port in .env +PORT=3001 + +# Then restart server +npm start +``` + +### Error: "CORS error in browser" +This is normal during development. The backend already has CORS enabled. + +--- + +## 📊 Database Credentials + +``` +Server: 172.20.235.176 +Database: AccManager +User: sa +Password: robotics@2020 +``` + +--- + +## ✅ Verification Checklist + +- [ ] Node.js installed +- [ ] npm packages installed (`npm install`) +- [ ] Backend server running (`npm start`) +- [ ] Can access http://localhost:3000/api/health +- [ ] Can login with admin/admin +- [ ] Database shows tables and statistics +- [ ] Frontend connects to backend + +--- + +## 📚 Additional Commands + +### Install Development Tools +```bash +npm install -D nodemon +npm run dev # Auto-restart on code changes +``` + +### Check npm packages +```bash +npm list +``` + +### Update packages +```bash +npm update +``` + +### Clear npm cache +```bash +npm cache clean --force +``` + +--- + +**For Support:** Check server logs for error messages diff --git a/accounts.html b/accounts.html deleted file mode 100644 index 4598273..0000000 --- a/accounts.html +++ /dev/null @@ -1,585 +0,0 @@ - - - - - - VaultSentinel - Accounts Management - - - - - - - - - - - - - -
- -
-
-
- search - -
-
-
- - -
-
- - -
-
-
-

Accounts Management

-

Administrative Access Control

-
- -
- - -
-
- Service - -
-
-
- - -
-
- - - - - - - - - - - - -
User OwnerAccount UsernameServiceActions
-
-
-
-
- - - - - - - - - - - - - diff --git a/applications.html b/applications.html deleted file mode 100644 index b5fe78d..0000000 --- a/applications.html +++ /dev/null @@ -1,575 +0,0 @@ - - - - - - VaultSentinel - Applications Management - - - - - - - - - - - - - -
- -
-
-
- search - -
-
-
- - -
-
- - -
-
-
-

Applications

-

Manage and monitor active infrastructure services.

-
- -
- - -
-
-
- lan -
-
-

Active

-

0

-
-
-
-
- bolt -
-
-

Total

-

0

-
-
-
-
- database -
-
-

Health

-

99.9%

-
-
-
- - -
-
-

Registered Services

-
- search - -
-
-
- - - - - - - - - - - - -
NameTypeStatusActions
-
-
-
-
- - - - - - - - - - - - - diff --git a/database/run-setup.ps1 b/database/run-setup.ps1 new file mode 100644 index 0000000..3d8dcfa --- /dev/null +++ b/database/run-setup.ps1 @@ -0,0 +1,63 @@ +# PowerShell Script to Execute SQL Server Setup +# Database: AccManager +# Server: 172.20.235.176 + +# SQL Server Connection Info +$ServerName = "172.20.235.176" +$Username = "sa" +$Password = "robotics@2020" +$SqlScriptPath = ".\setup.sql" + +Write-Host "========================================" -ForegroundColor Cyan +Write-Host "AccManager Database Setup" -ForegroundColor Cyan +Write-Host "========================================" -ForegroundColor Cyan +Write-Host "" + +# Check if sqlcmd is available +if (-not (Get-Command sqlcmd -ErrorAction SilentlyContinue)) { + Write-Host "ERROR: sqlcmd is not available on this system." -ForegroundColor Red + Write-Host "Please install SQL Server Command Line Tools (sqlcmd)" -ForegroundColor Yellow + Write-Host "Download from: https://docs.microsoft.com/en-us/sql/tools/sqlcmd-utility" -ForegroundColor Yellow + exit +} + +# Check if SQL script file exists +if (-not (Test-Path $SqlScriptPath)) { + Write-Host "ERROR: SQL script file not found: $SqlScriptPath" -ForegroundColor Red + exit +} + +Write-Host "Server: $ServerName" -ForegroundColor Green +Write-Host "User: $Username" -ForegroundColor Green +Write-Host "Script: $SqlScriptPath" -ForegroundColor Green +Write-Host "" + +# Execute SQL Script +Write-Host "Executing SQL script..." -ForegroundColor Yellow +Write-Host "" + +try { + sqlcmd -S $ServerName -U $Username -P $Password -i $SqlScriptPath -o "setup_output.log" + + Write-Host "" + Write-Host "========================================" -ForegroundColor Green + Write-Host "SETUP COMPLETED SUCCESSFULLY!" -ForegroundColor Green + Write-Host "========================================" -ForegroundColor Green + Write-Host "" + Write-Host "Output saved to: setup_output.log" -ForegroundColor Cyan + Write-Host "" + + # Display output + Write-Host "Setup Output:" -ForegroundColor Cyan + Get-Content "setup_output.log" +} +catch { + Write-Host "ERROR executing SQL script:" -ForegroundColor Red + Write-Host $_.Exception.Message -ForegroundColor Red + exit +} + +Write-Host "" +Write-Host "========================================" -ForegroundColor Green +Write-Host "Database is ready to use!" -ForegroundColor Green +Write-Host "========================================" -ForegroundColor Green diff --git a/database/setup.sql b/database/setup.sql new file mode 100644 index 0000000..6feaa60 --- /dev/null +++ b/database/setup.sql @@ -0,0 +1,168 @@ +-- =========================================== +-- SQL Server Setup Script for AccManager +-- Database: AccManager +-- Server: 172.20.235.176 +-- =========================================== + +-- Create Database +IF NOT EXISTS (SELECT name FROM sys.databases WHERE name = 'AccManager') +BEGIN + CREATE DATABASE AccManager; + PRINT 'Database AccManager created successfully.'; +END +ELSE +BEGIN + PRINT 'Database AccManager already exists.'; +END + +USE AccManager; + +-- =========================================== +-- 1. CREATE USERS TABLE +-- =========================================== +IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'Users') +BEGIN + CREATE TABLE Users ( + UserId INT PRIMARY KEY IDENTITY(1,1), + Username NVARCHAR(50) UNIQUE NOT NULL, + Password NVARCHAR(255) NOT NULL, + Email NVARCHAR(100), + FullName NVARCHAR(100), + Role NVARCHAR(50) NOT NULL, + Status NVARCHAR(20) DEFAULT 'Active', + CreatedDate DATETIME DEFAULT GETDATE(), + LastLogin DATETIME, + IsActive BIT DEFAULT 1 + ); + PRINT 'Table Users created successfully.'; +END + +-- =========================================== +-- 2. CREATE APPLICATIONS TABLE +-- =========================================== +IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'Applications') +BEGIN + CREATE TABLE Applications ( + AppId INT PRIMARY KEY IDENTITY(1,1), + Name NVARCHAR(100) NOT NULL, + Type NVARCHAR(50), + Status NVARCHAR(20) DEFAULT 'online', + Icon NVARCHAR(50), + Description NVARCHAR(500), + CreatedDate DATETIME DEFAULT GETDATE(), + UpdatedDate DATETIME DEFAULT GETDATE() + ); + PRINT 'Table Applications created successfully.'; +END + +-- =========================================== +-- 3. CREATE ACCOUNTS TABLE +-- =========================================== +IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'Accounts') +BEGIN + CREATE TABLE Accounts ( + AccountId INT PRIMARY KEY IDENTITY(1,1), + UserId INT NOT NULL, + AppId INT NOT NULL, + AccountUsername NVARCHAR(100), + AccountPassword NVARCHAR(255), + Email NVARCHAR(100), + AccessLevel NVARCHAR(50), + Status NVARCHAR(20) DEFAULT 'Active', + Notes NVARCHAR(MAX), + CreatedDate DATETIME DEFAULT GETDATE(), + UpdatedDate DATETIME DEFAULT GETDATE(), + FOREIGN KEY (UserId) REFERENCES Users(UserId) ON DELETE CASCADE, + FOREIGN KEY (AppId) REFERENCES Applications(AppId) ON DELETE CASCADE + ); + PRINT 'Table Accounts created successfully.'; +END + +-- =========================================== +-- 4. CREATE AUDIT LOG TABLE +-- =========================================== +IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'AuditLog') +BEGIN + CREATE TABLE AuditLog ( + LogId INT PRIMARY KEY IDENTITY(1,1), + UserId INT, + Action NVARCHAR(50), + TableName NVARCHAR(50), + RecordId INT, + OldValue NVARCHAR(MAX), + NewValue NVARCHAR(MAX), + Timestamp DATETIME DEFAULT GETDATE(), + FOREIGN KEY (UserId) REFERENCES Users(UserId) + ); + PRINT 'Table AuditLog created successfully.'; +END + +-- =========================================== +-- 5. CREATE INDEXES +-- =========================================== +IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name = 'IX_Users_Username') +BEGIN + CREATE INDEX IX_Users_Username ON Users(Username); +END + +IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name = 'IX_Accounts_UserId') +BEGIN + CREATE INDEX IX_Accounts_UserId ON Accounts(UserId); +END + +IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name = 'IX_Accounts_AppId') +BEGIN + CREATE INDEX IX_Accounts_AppId ON Accounts(AppId); +END + +PRINT 'Indexes created successfully.'; + +-- =========================================== +-- 6. INSERT INITIAL DATA +-- =========================================== + +-- Check if admin user exists +IF NOT EXISTS (SELECT * FROM Users WHERE Username = 'admin') +BEGIN + INSERT INTO Users (Username, Password, Email, FullName, Role, Status, IsActive) + VALUES ('admin', 'admin', 'admin@accmanager.local', 'Administrator', 'admin', 'Active', 1); + PRINT 'Admin user created: Username=admin, Password=admin'; +END + +-- Insert sample applications +IF (SELECT COUNT(*) FROM Applications) = 0 +BEGIN + INSERT INTO Applications (Name, Type, Status, Icon, Description) + VALUES + ('AWS', 'Cloud', 'online', 'cloud', 'Amazon Web Services - Cloud Computing'), + ('GitHub', 'VCS', 'online', 'code', 'GitHub - Version Control System'), + ('Google Workspace', 'Collaboration', 'online', 'mail', 'Google Workspace - Email and Collaboration'), + ('Nginx Proxy', 'Infra', 'offline', 'dns', 'Nginx - Web Server and Reverse Proxy'); + PRINT 'Sample applications inserted successfully.'; +END + +-- =========================================== +-- 7. DISPLAY DATABASE INFORMATION +-- =========================================== +PRINT ''; +PRINT '========================================'; +PRINT 'DATABASE SETUP COMPLETED SUCCESSFULLY'; +PRINT '========================================'; +PRINT ''; +PRINT 'Database Name: AccManager'; +PRINT ''; +PRINT 'Tables created:'; +SELECT ' - ' + name AS TableName FROM sys.tables ORDER BY name; +PRINT ''; +PRINT 'Users in system:'; +SELECT ' Username: ' + Username + ' | Role: ' + Role + ' | Status: ' + Status AS UserInfo FROM Users; +PRINT ''; +PRINT 'Applications available:'; +SELECT ' - ' + Name + ' (' + Type + ') - ' + Status AS AppInfo FROM Applications ORDER BY Name; +PRINT ''; +PRINT 'Login Credentials:'; +PRINT ' Username: admin'; +PRINT ' Password: admin'; +PRINT ' Role: admin'; +PRINT ''; +PRINT '========================================'; diff --git a/dialog.html b/dialog.html deleted file mode 100644 index 476ee7b..0000000 --- a/dialog.html +++ /dev/null @@ -1,224 +0,0 @@ - - - - - -Sentinel Accounts - Account Details - - - - - - - - - -
- -
-
Sentinel Accounts
-
-notifications -help_outline -
-
-
- - - -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
- -
- -
-
-Resource Details -

Account Details

-
- -
- -
- -
-
-cloud -
-
-
Cloud Infrastructure
-
AWS Production
-
-
-Active -
-
- -
- -
- -
-alternate_email -admin.aws_prod - -
-
- -
- -
-lock -••••••••••••••• - -
-
-
- -
- -
-Alex Rivera Profile -
-
Account Owner
-
Alex Rivera
-
-
- -
-
Date Created
-
-calendar_today - Oct 24, 2023 -
-
-
-
- -
- - -
-
-
- \ No newline at end of file diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..13c7d08 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,134 @@ +# Robot Account Manager - Project Structure + +## Directory Organization + +``` +AccManager/ +├── pages/ # HTML pages +│ ├── login.html # Login page (entry point) +│ ├── index.html # Dashboard +│ ├── accounts.html # Accounts management +│ └── applications.html # Applications management +├── js/ # JavaScript files +│ └── app.js # Main application logic +├── docs/ # Documentation +│ └── README.md # This file +├── index.html # Root redirect to pages/login.html +├── .git/ # Version control +├── .vscode/ # VS Code settings +└── README.md # Project root README +``` + +## Quick Start + +1. **Access the application:** + - Open `index.html` in a browser + - You will be automatically redirected to `pages/login.html` + +2. **Login Credentials (Demo):** + - Username: `admin` + - Password: `admin` + +3. **Features:** + - Dashboard: Overview of accounts and applications + - Accounts: Manage user accounts for various services + - Applications: Manage connected applications/services + +## File Structure Explanation + +### /pages/ +Contains all HTML pages with updated relative paths for script imports: +- `login.html` - Authentication page +- `index.html` - Main dashboard +- `accounts.html` - Accounts management interface +- `applications.html` - Applications management interface + +All pages reference scripts using `../js/app.js` for correct path resolution. + +### /js/ +Application logic and state management: +- `app.js` - Main AccountManager class with all functionality + +### /docs/ +Documentation files for reference and development. + +## Application Architecture + +### AccountManager Class (app.js) +- **Storage**: Uses localStorage for data persistence +- **Pages**: Dynamically renders content based on user navigation +- **Authentication**: Checks for valid session on page load +- **Modals**: Manages adding/editing accounts and applications + +### Data Storage +Application stores data in browser's localStorage: +- `currentUser` - Logged-in user information +- `accounts` - List of managed accounts +- `applications` - List of managed applications +- `rememberedUsername` - Optional saved username + +## Development Notes + +- **Framework**: Tailwind CSS for styling +- **Icons**: Material Design symbols +- **Storage**: Browser localStorage (client-side only) +- **Responsive**: Built with mobile-first approach +- **Modern**: ES6+ JavaScript features + +## Navigation Flow + +``` +index.html (root) + ↓ +pages/login.html + ↓ (after login) +pages/index.html (dashboard) + ├→ pages/accounts.html + └→ pages/applications.html +``` + +## Features + +### Authentication +- Username/password login +- Session management +- Remember me functionality +- Logout with confirmation + +### Dashboard +- Overview statistics +- Recent account activity +- Quick access to management pages + +### Account Management +- Add new accounts +- Edit existing accounts +- Delete accounts +- Filter by service +- View account details + +### Application Management +- Add new applications +- Edit application details +- Delete applications +- View application status (online/offline) +- Health monitoring + +## Browser Compatibility + +- Modern browsers (Chrome, Firefox, Safari, Edge) +- Requires JavaScript enabled +- Uses localStorage API + +## Future Improvements + +- Server-side authentication +- Database integration +- Advanced filtering and search +- User roles and permissions +- Audit logging +- Dark mode toggle persistence + +--- +Generated: March 27, 2026 +Version: 1.0.0 diff --git a/index.html b/index.html index dffacae..c8fbb5d 100644 --- a/index.html +++ b/index.html @@ -1,172 +1,12 @@ - + - - - VaultSentinel - Account Management System - - - - - - - - - - - - -
- -
-
-
- search - -
-
-
- - -
-
- - -
- -
-
- - + + Redirecting to login... diff --git a/install-nodejs.ps1 b/install-nodejs.ps1 new file mode 100644 index 0000000..c4490e5 --- /dev/null +++ b/install-nodejs.ps1 @@ -0,0 +1,35 @@ +# Install Node.js automatically (Run as Administrator) + +Write-Host "Installing Node.js LTS..." -ForegroundColor Green + +# Check if winget is available +if (Get-Command winget -ErrorAction SilentlyContinue) { + Write-Host "Found winget, installing Node.js..." -ForegroundColor Cyan + winget install OpenJS.NodeJS +} +else { + Write-Host "winget not found. Downloading Node.js installer..." -ForegroundColor Yellow + + # Download Node.js LTS + $NodeURL = "https://nodejs.org/dist/v18.16.0/node-v18.16.0-x64.msi" + $InstallerPath = "$env:TEMP\nodejs-installer.msi" + + Write-Host "Downloading from: $NodeURL" + Invoke-WebRequest -Uri $NodeURL -OutFile $InstallerPath -UseBasicParsing + + Write-Host "Running installer..." -ForegroundColor Cyan + Start-Process -FilePath "msiexec.exe" -ArgumentList "/i $InstallerPath /quiet /norestart" -Wait + + Remove-Item $InstallerPath +} + +Write-Host "Installation complete! Refreshing environment..." -ForegroundColor Green + +# Refresh PATH +$env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User") + +Write-Host "Checking installation..." -ForegroundColor Cyan +node --version +npm --version + +Write-Host "Ready to run npm install!" -ForegroundColor Green diff --git a/app.js b/js/app.js similarity index 94% rename from app.js rename to js/app.js index ff98fd6..9085f9d 100644 --- a/app.js +++ b/js/app.js @@ -3,6 +3,14 @@ class AccountManager { constructor() { + // Check if user is logged in + const currentUser = this.loadFromStorage('currentUser'); + if (!currentUser) { + window.location.href = '../pages/login.html'; + return; + } + + this.currentUser = currentUser; this.accounts = this.loadFromStorage('accounts') || []; this.applications = this.loadFromStorage('applications') || [ { id: 1, name: 'AWS', type: 'Cloud', status: 'online', icon: 'cloud' }, @@ -52,10 +60,36 @@ class AccountManager { appForm.addEventListener('submit', (e) => this.handleAppSubmit(e)); } + // Logout button + const logoutBtn = document.getElementById('logoutBtn'); + if (logoutBtn) { + logoutBtn.addEventListener('click', () => this.handleLogout()); + } + + // Update account display + this.updateAccountDisplay(); + // Account table row clicks this.setupAccountRowListeners(); } + updateAccountDisplay() { + // Use the logged-in user from constructor + const usernameEl = document.getElementById('accountUsername'); + const roleEl = document.getElementById('accountRole'); + + if (usernameEl) usernameEl.textContent = this.currentUser?.username || 'User'; + if (roleEl) roleEl.textContent = this.currentUser?.role || 'Administrator'; + } + + handleLogout() { + if (confirm('Are you sure you want to logout?')) { + this.saveToStorage('currentUser', null); + localStorage.clear(); + window.location.href = '../pages/login.html'; + } + } + renderDashboard() { return `
@@ -66,7 +100,7 @@ class AccountManager {

Account & Service Management

- + add Add Account @@ -125,7 +159,7 @@ class AccountManager {
` : `
-

No accounts yet. Create one

+

No accounts yet. Create one

`} @@ -385,7 +419,7 @@ class AccountManager { if (confirm('Delete this account?')) { this.accounts.splice(accountId, 1); this.saveToStorage('accounts', this.accounts); - location.href = 'accounts.html'; + location.href = './accounts.html'; } }); }); @@ -410,7 +444,7 @@ class AccountManager { if (confirm('Delete this application?')) { this.applications.splice(appId, 1); this.saveToStorage('applications', this.applications); - location.href = 'applications.html'; + location.href = './applications.html'; } }); }); @@ -447,7 +481,7 @@ class AccountManager { this.saveToStorage('accounts', this.accounts); this.closeModals(); - location.href = 'accounts.html'; + location.href = './accounts.html'; } handleAppSubmit(e) { @@ -468,7 +502,7 @@ class AccountManager { this.saveToStorage('applications', this.applications); this.closeModals(); - location.href = 'applications.html'; + location.href = './applications.html'; } openAccountModal() { diff --git a/navbar.js b/navbar.js deleted file mode 100644 index e5cfb85..0000000 --- a/navbar.js +++ /dev/null @@ -1,76 +0,0 @@ -// Shared Navigation Module for VaultSentinel -// Renders sidebar navigation on all pages - -function createNavbar(currentPage = 'dashboard') { - const navHTML = ` - - - - -
-
-
- search - -
-
-
- - -
-
- `; - - return navHTML; -} - -// Function to inject navbar (call this from each page) -function injectNavbar(currentPage = 'dashboard') { - const navbarWrapper = document.createElement('div'); - navbarWrapper.className = 'flex h-screen w-screen'; - navbarWrapper.innerHTML = createNavbar(currentPage); - - // Move body content into main section - const mainSection = document.createElement('main'); - mainSection.className = 'flex-1 flex flex-col h-screen min-w-0 overflow-hidden'; - mainSection.innerHTML = document.body.innerHTML; - - // Clear body and rebuild structure - document.body.innerHTML = ''; - document.body.classList.add('flex', 'h-screen', 'w-screen', 'antialiased'); - - // Insert navbar + main content - document.body.appendChild(navbarWrapper); - navbarWrapper.appendChild(mainSection); -} diff --git a/package.json b/package.json new file mode 100644 index 0000000..fe36208 --- /dev/null +++ b/package.json @@ -0,0 +1,22 @@ +{ + "name": "accmanager-backend", + "version": "1.0.0", + "description": "Backend server for AccManager application", + "main": "server.js", + "scripts": { + "start": "node server.js", + "dev": "nodemon server.js" + }, + "keywords": ["accmanager", "backend", "express", "mssql"], + "author": "", + "license": "MIT", + "dependencies": { + "express": "^4.18.2", + "mssql": "^9.1.1", + "cors": "^2.8.5", + "dotenv": "^16.3.1" + }, + "devDependencies": { + "nodemon": "^3.0.1" + } +} diff --git a/pages/accounts.html b/pages/accounts.html new file mode 100644 index 0000000..61cbf6a --- /dev/null +++ b/pages/accounts.html @@ -0,0 +1,152 @@ + + + + + + VaultSentinel - Accounts Management + + + + + + + + + + +
+
+
+
+ search + +
+
+
+
+ account_circle +
+ User Account + Administrator +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/pages/applications.html b/pages/applications.html new file mode 100644 index 0000000..69f819b --- /dev/null +++ b/pages/applications.html @@ -0,0 +1,152 @@ + + + + + + VaultSentinel - Applications Management + + + + + + + + + + +
+
+
+
+ search + +
+
+
+
+ account_circle +
+ User Account + Administrator +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/pages/index.html b/pages/index.html new file mode 100644 index 0000000..e4a6ce5 --- /dev/null +++ b/pages/index.html @@ -0,0 +1,176 @@ + + + + + + Robot Manager Account - Account Management System + + + + + + + + + + + + + +
+ +
+
+
+ search + +
+
+
+
+ account_circle +
+ User Account + Administrator +
+
+ +
+
+ + +
+ +
+
+ + + + diff --git a/pages/login.html b/pages/login.html new file mode 100644 index 0000000..48a2718 --- /dev/null +++ b/pages/login.html @@ -0,0 +1,254 @@ + + + + + + VaultSentinel - Login + + + + + + + + + +
+
+ +
+ +
+
+
+ security +
+
+

VaultSentinel

+

Account Management System

+
+ + +
+ +
+ +
+ + person + + +
+
+ + +
+ +
+ + lock + + +
+
+ + +
+ + +
+ + + + + + +
+ + +
+

Default credentials for demo: admin / admin

+
+
+ + +
+

v1.0.0

+
+
+
+ + + + diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..dde3c21 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,4 @@ +Flask==2.3.2 +Flask-CORS==4.0.0 +pyodbc==4.0.35 +python-dotenv==1.0.0 diff --git a/server.js b/server.js new file mode 100644 index 0000000..499f842 --- /dev/null +++ b/server.js @@ -0,0 +1,438 @@ +// Backend Server for AccManager +// Express.js + mssql + +const express = require('express'); +const sql = require('mssql'); +const cors = require('cors'); +const app = express(); + +// Middleware +app.use(cors()); +app.use(express.json()); + +// SQL Server Configuration +const sqlConfig = { + server: '172.20.235.176', + authentication: { + type: 'default', + options: { + userName: 'sa', + password: 'robotics@2020' + } + }, + options: { + database: 'AccManager', + trustServerCertificate: true, + enableKeepAlive: true, + connectTimeout: 30000 + } +}; + +// Initialize Database Pool +let pool; + +async function initializeDatabase() { + try { + pool = new sql.ConnectionPool(sqlConfig); + await pool.connect(); + console.log('✓ Connected to SQL Server'); + + // Check and create database if not exists + const masterConnection = new sql.ConnectionPool({ + server: '172.20.235.176', + authentication: { type: 'default', options: { userName: 'sa', password: 'robotics@2020' } }, + options: { connectTimeout: 30000, database: 'master', trustServerCertificate: true } + }); + + await masterConnection.connect(); + const createDbResult = await masterConnection.request() + .query(`IF NOT EXISTS (SELECT name FROM sys.databases WHERE name = 'AccManager') + BEGIN + CREATE DATABASE AccManager; + END`); + await masterConnection.close(); + + // Now create tables in AccManager + await createTables(); + console.log('✓ Database and tables created'); + + } catch (err) { + console.error('Database connection failed:', err); + process.exit(1); + } +} + +async function createTables() { + const queries = [ + // Users Table + `IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'Users') + BEGIN + CREATE TABLE Users ( + UserId INT PRIMARY KEY IDENTITY(1,1), + Username NVARCHAR(50) UNIQUE NOT NULL, + Password NVARCHAR(255) NOT NULL, + Email NVARCHAR(100), + FullName NVARCHAR(100), + Role NVARCHAR(50) NOT NULL, + Status NVARCHAR(20) DEFAULT 'Active', + CreatedDate DATETIME DEFAULT GETDATE(), + LastLogin DATETIME, + IsActive BIT DEFAULT 1 + ) + END`, + + // Applications Table + `IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'Applications') + BEGIN + CREATE TABLE Applications ( + AppId INT PRIMARY KEY IDENTITY(1,1), + Name NVARCHAR(100) NOT NULL, + Type NVARCHAR(50), + Status NVARCHAR(20) DEFAULT 'online', + Icon NVARCHAR(50), + Description NVARCHAR(500), + CreatedDate DATETIME DEFAULT GETDATE(), + UpdatedDate DATETIME DEFAULT GETDATE() + ) + END`, + + // Accounts Table + `IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'Accounts') + BEGIN + CREATE TABLE Accounts ( + AccountId INT PRIMARY KEY IDENTITY(1,1), + UserId INT NOT NULL, + AppId INT NOT NULL, + AccountUsername NVARCHAR(100), + AccountPassword NVARCHAR(255), + Email NVARCHAR(100), + AccessLevel NVARCHAR(50), + Status NVARCHAR(20) DEFAULT 'Active', + Notes NVARCHAR(MAX), + CreatedDate DATETIME DEFAULT GETDATE(), + UpdatedDate DATETIME DEFAULT GETDATE(), + FOREIGN KEY (UserId) REFERENCES Users(UserId) ON DELETE CASCADE, + FOREIGN KEY (AppId) REFERENCES Applications(AppId) ON DELETE CASCADE + ) + END`, + + // AuditLog Table + `IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'AuditLog') + BEGIN + CREATE TABLE AuditLog ( + LogId INT PRIMARY KEY IDENTITY(1,1), + UserId INT, + Action NVARCHAR(50), + TableName NVARCHAR(50), + RecordId INT, + OldValue NVARCHAR(MAX), + NewValue NVARCHAR(MAX), + Timestamp DATETIME DEFAULT GETDATE(), + FOREIGN KEY (UserId) REFERENCES Users(UserId) + ) + END` + ]; + + for (let query of queries) { + try { + await pool.request().query(query); + } catch (err) { + console.error('Table creation error:', err.message); + } + } + + // Insert initial admin user + try { + await pool.request() + .input('username', sql.NVarChar, 'admin') + .input('password', sql.NVarChar, 'admin') + .input('email', sql.NVarChar, 'admin@accmanager.local') + .input('fullname', sql.NVarChar, 'Administrator') + .input('role', sql.NVarChar, 'admin') + .query(`IF NOT EXISTS (SELECT * FROM Users WHERE Username = @username) + INSERT INTO Users (Username, Password, Email, FullName, Role, IsActive) + VALUES (@username, @password, @email, @fullname, @role, 1)`); + console.log('✓ Admin user created: admin / admin'); + } catch (err) { + console.error('Admin user error:', err.message); + } + + // Insert sample applications + try { + await pool.request() + .query(`IF (SELECT COUNT(*) FROM Applications) = 0 + BEGIN + INSERT INTO Applications (Name, Type, Status, Icon, Description) + VALUES + ('AWS', 'Cloud', 'online', 'cloud', 'Amazon Web Services'), + ('GitHub', 'VCS', 'online', 'code', 'GitHub - Version Control'), + ('Google Workspace', 'Collaboration', 'online', 'mail', 'Google Workspace'), + ('Nginx Proxy', 'Infra', 'offline', 'dns', 'Nginx Web Server') + END`); + console.log('✓ Sample applications created'); + } catch (err) { + console.error('Applications error:', err.message); + } +} + +// ========================================== +// API ROUTES - Authentication +// ========================================== + +// Login endpoint +app.post('/api/auth/login', async (req, res) => { + try { + const { username, password } = req.body; + + const result = await pool.request() + .input('username', sql.NVarChar, username) + .input('password', sql.NVarChar, password) + .query('SELECT UserId, Username, Email, FullName, Role, Status FROM Users WHERE Username = @username AND Password = @password AND IsActive = 1'); + + if (result.recordset.length > 0) { + const user = result.recordset[0]; + + // Update last login + await pool.request() + .input('userId', sql.Int, user.UserId) + .query('UPDATE Users SET LastLogin = GETDATE() WHERE UserId = @userId'); + + res.json({ + success: true, + message: 'Login successful', + user: user + }); + } else { + res.status(401).json({ + success: false, + message: 'Invalid username or password' + }); + } + } catch (err) { + console.error('Login error:', err); + res.status(500).json({ success: false, message: err.message }); + } +}); + +// ========================================== +// API ROUTES - Users +// ========================================== + +// Get all users +app.get('/api/users', async (req, res) => { + try { + const result = await pool.request() + .query('SELECT UserId, Username, Email, FullName, Role, Status, CreatedDate FROM Users ORDER BY CreatedDate DESC'); + res.json({ success: true, data: result.recordset }); + } catch (err) { + res.status(500).json({ success: false, message: err.message }); + } +}); + +// Get user by ID +app.get('/api/users/:id', async (req, res) => { + try { + const result = await pool.request() + .input('userId', sql.Int, req.params.id) + .query('SELECT * FROM Users WHERE UserId = @userId'); + + if (result.recordset.length > 0) { + res.json({ success: true, data: result.recordset[0] }); + } else { + res.status(404).json({ success: false, message: 'User not found' }); + } + } catch (err) { + res.status(500).json({ success: false, message: err.message }); + } +}); + +// Create new user +app.post('/api/users', async (req, res) => { + try { + const { username, password, email, fullname, role } = req.body; + + const result = await pool.request() + .input('username', sql.NVarChar, username) + .input('password', sql.NVarChar, password) + .input('email', sql.NVarChar, email) + .input('fullname', sql.NVarChar, fullname) + .input('role', sql.NVarChar, role) + .query(`INSERT INTO Users (Username, Password, Email, FullName, Role, IsActive) + VALUES (@username, @password, @email, @fullname, @role, 1); + SELECT SCOPE_IDENTITY() as UserId`); + + res.json({ success: true, message: 'User created', userId: result.recordset[0].UserId }); + } catch (err) { + res.status(500).json({ success: false, message: err.message }); + } +}); + +// ========================================== +// API ROUTES - Applications +// ========================================== + +// Get all applications +app.get('/api/applications', async (req, res) => { + try { + const result = await pool.request() + .query('SELECT * FROM Applications ORDER BY Name'); + res.json({ success: true, data: result.recordset }); + } catch (err) { + res.status(500).json({ success: false, message: err.message }); + } +}); + +// Create application +app.post('/api/applications', async (req, res) => { + try { + const { name, type, status, icon, description } = req.body; + + const result = await pool.request() + .input('name', sql.NVarChar, name) + .input('type', sql.NVarChar, type) + .input('status', sql.NVarChar, status) + .input('icon', sql.NVarChar, icon) + .input('description', sql.NVarChar, description) + .query(`INSERT INTO Applications (Name, Type, Status, Icon, Description) + VALUES (@name, @type, @status, @icon, @description); + SELECT SCOPE_IDENTITY() as AppId`); + + res.json({ success: true, message: 'Application created', appId: result.recordset[0].AppId }); + } catch (err) { + res.status(500).json({ success: false, message: err.message }); + } +}); + +// ========================================== +// API ROUTES - Accounts +// ========================================== + +// Get accounts for a user +app.get('/api/accounts/user/:userId', async (req, res) => { + try { + const result = await pool.request() + .input('userId', sql.Int, req.params.userId) + .query(`SELECT a.*, app.Name as AppName, app.Type as AppType + FROM Accounts a + JOIN Applications app ON a.AppId = app.AppId + WHERE a.UserId = @userId + ORDER BY a.CreatedDate DESC`); + res.json({ success: true, data: result.recordset }); + } catch (err) { + res.status(500).json({ success: false, message: err.message }); + } +}); + +// Create account +app.post('/api/accounts', async (req, res) => { + try { + const { userId, appId, accountUsername, accountPassword, email, accessLevel, notes } = req.body; + + const result = await pool.request() + .input('userId', sql.Int, userId) + .input('appId', sql.Int, appId) + .input('accountUsername', sql.NVarChar, accountUsername) + .input('accountPassword', sql.NVarChar, accountPassword) + .input('email', sql.NVarChar, email) + .input('accessLevel', sql.NVarChar, accessLevel) + .input('notes', sql.NVarChar, notes) + .query(`INSERT INTO Accounts (UserId, AppId, AccountUsername, AccountPassword, Email, AccessLevel, Notes) + VALUES (@userId, @appId, @accountUsername, @accountPassword, @email, @accessLevel, @notes); + SELECT SCOPE_IDENTITY() as AccountId`); + + res.json({ success: true, message: 'Account created', accountId: result.recordset[0].AccountId }); + } catch (err) { + res.status(500).json({ success: false, message: err.message }); + } +}); + +// ========================================== +// API ROUTES - Database Info +// ========================================== + +// Get database information +app.get('/api/database/info', async (req, res) => { + try { + const tables = await pool.request().query(` + SELECT TABLE_NAME as TableName, + (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = t.TABLE_NAME) as ColumnCount + FROM INFORMATION_SCHEMA.TABLES t + WHERE TABLE_SCHEMA = 'dbo' + ORDER BY TABLE_NAME + `); + + const users = await pool.request().query('SELECT COUNT(*) as Count FROM Users'); + const apps = await pool.request().query('SELECT COUNT(*) as Count FROM Applications'); + const accounts = await pool.request().query('SELECT COUNT(*) as Count FROM Accounts'); + + res.json({ + success: true, + database: 'AccManager', + server: '172.20.235.176', + tables: tables.recordset, + statistics: { + users: users.recordset[0].Count, + applications: apps.recordset[0].Count, + accounts: accounts.recordset[0].Count + } + }); + } catch (err) { + res.status(500).json({ success: false, message: err.message }); + } +}); + +// Health check +app.get('/api/health', (req, res) => { + res.json({ status: 'OK', database: 'Connected' }); +}); + +// ========================================== +// Error Handling +// ========================================== + +app.use((err, req, res, next) => { + console.error(err); + res.status(500).json({ success: false, message: err.message }); +}); + +// ========================================== +// Server Startup +// ========================================== + +const PORT = process.env.PORT || 3000; + +async function startServer() { + try { + await initializeDatabase(); + + app.listen(PORT, () => { + console.log(`\n========================================`); + console.log(`AccManager Backend Server`); + console.log(`========================================`); + console.log(`✓ Server running on http://localhost:${PORT}`); + console.log(`✓ Database: AccManager`); + console.log(`✓ Default admin: admin / admin`); + console.log(`\nAPI Endpoints:`); + console.log(` POST /api/auth/login`); + console.log(` GET /api/database/info`); + console.log(` GET /api/users`); + console.log(` GET /api/applications`); + console.log(` GET /api/accounts/user/:userId`); + console.log(`========================================\n`); + }); + } catch (err) { + console.error('Failed to start server:', err); + process.exit(1); + } +} + +// Graceful shutdown +process.on('SIGINT', async () => { + console.log('\nShutting down...'); + if (pool) { + await pool.close(); + } + process.exit(0); +}); + +startServer(); diff --git a/server_python.py b/server_python.py new file mode 100644 index 0000000..c5981bc --- /dev/null +++ b/server_python.py @@ -0,0 +1,480 @@ +# AccManager Backend Server (Python Alternative) +# Requirements: Python 3.8+, Flask, pyodbc + +from flask import Flask, request, jsonify, render_template +from flask_cors import CORS +from datetime import datetime +import pyodbc +import json +import os +from dotenv import load_dotenv + +load_dotenv() + +app = Flask(__name__) +CORS(app) + +# SQL Server Connection Settings +DB_SERVER = os.getenv('DB_SERVER', '172.20.235.176') +DB_USER = os.getenv('DB_USER', 'sa') +DB_PASSWORD = os.getenv('DB_PASSWORD', 'robotics@2020') +DB_NAME = os.getenv('DB_NAME', 'AccManager') + +# Connection string +CONNECTION_STRING = f''' + Driver={{ODBC Driver 17 for SQL Server}}; + Server={DB_SERVER}; + Database={DB_NAME}; + UID={DB_USER}; + PWD={DB_PASSWORD}; + TrustServerCertificate=yes; +''' + +# Initialize database connection +def get_db_connection(): + try: + conn = pyodbc.connect(CONNECTION_STRING) + return conn + except Exception as e: + print(f"Database connection error: {e}") + return None + +# Create tables +def create_tables(): + conn = get_db_connection() + if not conn: + return False + + cursor = conn.cursor() + + try: + # Users table + cursor.execute(''' + IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'Users') + BEGIN + CREATE TABLE Users ( + UserId INT PRIMARY KEY IDENTITY(1,1), + Username NVARCHAR(50) UNIQUE NOT NULL, + Password NVARCHAR(255) NOT NULL, + Email NVARCHAR(100), + FullName NVARCHAR(100), + Role NVARCHAR(50) NOT NULL, + Status NVARCHAR(20) DEFAULT 'Active', + CreatedDate DATETIME DEFAULT GETDATE(), + LastLogin DATETIME, + IsActive BIT DEFAULT 1 + ) + END + ''') + + # Applications table + cursor.execute(''' + IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'Applications') + BEGIN + CREATE TABLE Applications ( + AppId INT PRIMARY KEY IDENTITY(1,1), + Name NVARCHAR(100) NOT NULL, + Type NVARCHAR(50), + Status NVARCHAR(20) DEFAULT 'online', + Icon NVARCHAR(50), + Description NVARCHAR(500), + CreatedDate DATETIME DEFAULT GETDATE(), + UpdatedDate DATETIME DEFAULT GETDATE() + ) + END + ''') + + # Accounts table + cursor.execute(''' + IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'Accounts') + BEGIN + CREATE TABLE Accounts ( + AccountId INT PRIMARY KEY IDENTITY(1,1), + UserId INT NOT NULL, + AppId INT NOT NULL, + AccountUsername NVARCHAR(100), + AccountPassword NVARCHAR(255), + Email NVARCHAR(100), + AccessLevel NVARCHAR(50), + Status NVARCHAR(20) DEFAULT 'Active', + Notes NVARCHAR(MAX), + CreatedDate DATETIME DEFAULT GETDATE(), + UpdatedDate DATETIME DEFAULT GETDATE(), + FOREIGN KEY (UserId) REFERENCES Users(UserId) ON DELETE CASCADE, + FOREIGN KEY (AppId) REFERENCES Applications(AppId) ON DELETE CASCADE + ) + END + ''') + + # AuditLog table + cursor.execute(''' + IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'AuditLog') + BEGIN + CREATE TABLE AuditLog ( + LogId INT PRIMARY KEY IDENTITY(1,1), + UserId INT, + Action NVARCHAR(50), + TableName NVARCHAR(50), + RecordId INT, + OldValue NVARCHAR(MAX), + NewValue NVARCHAR(MAX), + Timestamp DATETIME DEFAULT GETDATE(), + FOREIGN KEY (UserId) REFERENCES Users(UserId) + ) + END + ''') + + conn.commit() + + # Insert admin user + cursor.execute(''' + IF NOT EXISTS (SELECT * FROM Users WHERE Username = 'admin') + INSERT INTO Users (Username, Password, Email, FullName, Role, IsActive) + VALUES ('admin', 'admin', 'admin@accmanager.local', 'Administrator', 'admin', 1) + ''') + + # Insert sample applications + cursor.execute(''' + IF (SELECT COUNT(*) FROM Applications) = 0 + BEGIN + INSERT INTO Applications (Name, Type, Status, Icon, Description) + VALUES + ('AWS', 'Cloud', 'online', 'cloud', 'Amazon Web Services'), + ('GitHub', 'VCS', 'online', 'code', 'GitHub - Version Control'), + ('Google Workspace', 'Collaboration', 'online', 'mail', 'Google Workspace'), + ('Nginx Proxy', 'Infra', 'offline', 'dns', 'Nginx Web Server') + END + ''') + + conn.commit() + cursor.close() + conn.close() + return True + + except Exception as e: + print(f"Table creation error: {e}") + return False + +# ========================================== +# Routes: Health Check +# ========================================== + +@app.route('/api/health', methods=['GET']) +def health(): + conn = get_db_connection() + if conn: + conn.close() + return jsonify({"status": "OK", "database": "Connected"}), 200 + else: + return jsonify({"status": "ERROR", "database": "Disconnected"}), 500 + +# ========================================== +# Routes: Authentication +# ========================================== + +@app.route('/api/auth/login', methods=['POST']) +def login(): + try: + data = request.get_json() + username = data.get('username') + password = data.get('password') + + conn = get_db_connection() + if not conn: + return jsonify({"success": False, "message": "Database connection failed"}), 500 + + cursor = conn.cursor() + cursor.execute(''' + SELECT UserId, Username, Email, FullName, Role, Status + FROM Users + WHERE Username = ? AND Password = ? AND IsActive = 1 + ''', (username, password)) + + user = cursor.fetchone() + + if user: + cursor.execute('UPDATE Users SET LastLogin = GETDATE() WHERE UserId = ?', user[0]) + conn.commit() + + return jsonify({ + "success": True, + "message": "Login successful", + "user": { + "UserId": user[0], + "username": user[1], + "email": user[2], + "fullname": user[3], + "role": user[4], + "status": user[5] + } + }), 200 + else: + return jsonify({ + "success": False, + "message": "Invalid username or password" + }), 401 + + except Exception as e: + return jsonify({"success": False, "message": str(e)}), 500 + finally: + if conn: + conn.close() + +# ========================================== +# Routes: Users +# ========================================== + +@app.route('/api/users', methods=['GET']) +def get_users(): + try: + conn = get_db_connection() + if not conn: + return jsonify({"success": False, "message": "Database connection failed"}), 500 + + cursor = conn.cursor() + cursor.execute(''' + SELECT UserId, Username, Email, FullName, Role, Status, CreatedDate + FROM Users + ORDER BY CreatedDate DESC + ''') + + users = [] + for row in cursor.fetchall(): + users.append({ + "UserId": row[0], + "Username": row[1], + "Email": row[2], + "FullName": row[3], + "Role": row[4], + "Status": row[5], + "CreatedDate": str(row[6]) + }) + + return jsonify({"success": True, "data": users}), 200 + + except Exception as e: + return jsonify({"success": False, "message": str(e)}), 500 + finally: + if conn: + conn.close() + +@app.route('/api/users/', methods=['GET']) +def get_user(user_id): + try: + conn = get_db_connection() + if not conn: + return jsonify({"success": False, "message": "Database connection failed"}), 500 + + cursor = conn.cursor() + cursor.execute('SELECT * FROM Users WHERE UserId = ?', (user_id,)) + + user = cursor.fetchone() + + if user: + return jsonify({ + "success": True, + "data": {"UserId": user[0], "Username": user[1]} + }), 200 + else: + return jsonify({"success": False, "message": "User not found"}), 404 + + except Exception as e: + return jsonify({"success": False, "message": str(e)}), 500 + finally: + if conn: + conn.close() + +@app.route('/api/users', methods=['POST']) +def create_user(): + try: + data = request.get_json() + + conn = get_db_connection() + if not conn: + return jsonify({"success": False, "message": "Database connection failed"}), 500 + + cursor = conn.cursor() + cursor.execute(''' + INSERT INTO Users (Username, Password, Email, FullName, Role, IsActive) + VALUES (?, ?, ?, ?, ?, 1) + ''', (data['username'], data['password'], data['email'], + data['fullname'], data['role'])) + + conn.commit() + + return jsonify({ + "success": True, + "message": "User created" + }), 201 + + except Exception as e: + return jsonify({"success": False, "message": str(e)}), 500 + finally: + if conn: + conn.close() + +# ========================================== +# Routes: Applications +# ========================================== + +@app.route('/api/applications', methods=['GET']) +def get_applications(): + try: + conn = get_db_connection() + if not conn: + return jsonify({"success": False, "message": "Database connection failed"}), 500 + + cursor = conn.cursor() + cursor.execute('SELECT * FROM Applications ORDER BY Name') + + apps = [] + for row in cursor.fetchall(): + apps.append({ + "AppId": row[0], + "Name": row[1], + "Type": row[2], + "Status": row[3], + "Icon": row[4], + "Description": row[5] + }) + + return jsonify({"success": True, "data": apps}), 200 + + except Exception as e: + return jsonify({"success": False, "message": str(e)}), 500 + finally: + if conn: + conn.close() + +# ========================================== +# Routes: Accounts +# ========================================== + +@app.route('/api/accounts/user/', methods=['GET']) +def get_accounts(user_id): + try: + conn = get_db_connection() + if not conn: + return jsonify({"success": False, "message": "Database connection failed"}), 500 + + cursor = conn.cursor() + cursor.execute(''' + SELECT a.*, app.Name, app.Type + FROM Accounts a + JOIN Applications app ON a.AppId = app.AppId + WHERE a.UserId = ? + ORDER BY a.CreatedDate DESC + ''', (user_id,)) + + accounts = [] + for row in cursor.fetchall(): + accounts.append({ + "AccountId": row[0], + "UserId": row[1], + "AppId": row[2], + "AccountUsername": row[3], + "AccountPassword": row[4], + "AppName": row[12], + "AppType": row[13] + }) + + return jsonify({"success": True, "data": accounts}), 200 + + except Exception as e: + return jsonify({"success": False, "message": str(e)}), 500 + finally: + if conn: + conn.close() + +# ========================================== +# Routes: Database Info +# ========================================== + +@app.route('/api/database/info', methods=['GET']) +def database_info(): + try: + conn = get_db_connection() + if not conn: + return jsonify({"success": False, "message": "Database connection failed"}), 500 + + cursor = conn.cursor() + + # Get tables + cursor.execute(''' + SELECT TABLE_NAME + FROM INFORMATION_SCHEMA.TABLES + WHERE TABLE_SCHEMA = 'dbo' + ORDER BY TABLE_NAME + ''') + tables = [row[0] for row in cursor.fetchall()] + + # Get statistics + cursor.execute('SELECT COUNT(*) FROM Users') + user_count = cursor.fetchone()[0] + + cursor.execute('SELECT COUNT(*) FROM Applications') + app_count = cursor.fetchone()[0] + + cursor.execute('SELECT COUNT(*) FROM Accounts') + account_count = cursor.fetchone()[0] + + return jsonify({ + "success": True, + "database": "AccManager", + "server": DB_SERVER, + "tables": tables, + "statistics": { + "users": user_count, + "applications": app_count, + "accounts": account_count + } + }), 200 + + except Exception as e: + return jsonify({"success": False, "message": str(e)}), 500 + finally: + if conn: + conn.close() + +# ========================================== +# Error Handlers +# ========================================== + +@app.errorhandler(404) +def not_found(error): + return jsonify({"error": "Not found"}), 404 + +@app.errorhandler(500) +def server_error(error): + return jsonify({"error": "Internal server error"}), 500 + +# ========================================== +# Startup +# ========================================== + +if __name__ == '__main__': + print("\n========================================") + print("AccManager Backend Server (Python)") + print("========================================") + print(f"Server: {DB_SERVER}") + print(f"Database: {DB_NAME}") + print(f"User: {DB_USER}") + + # Initialize database + print("\nInitializing database...") + if create_tables(): + print("✓ Database tables created/verified") + else: + print("✗ Database initialization failed") + + print("\n✓ Server running on http://localhost:5000") + print("\nAPI Endpoints:") + print(" /api/health") + print(" /api/auth/login") + print(" /api/users") + print(" /api/applications") + print(" /api/accounts/user/") + print(" /api/database/info") + print("========================================\n") + + app.run(debug=True, host='localhost', port=5000) diff --git a/start.html b/start.html deleted file mode 100644 index e2d9a90..0000000 --- a/start.html +++ /dev/null @@ -1,242 +0,0 @@ - - - - - - VaultSentinel - Trung Tâm Điều Khiển - - - -
- -
-

🔐 VaultSentinel

-

Ứng Dụng Quản Lý Tài Khoản Dịch Vụ - Phiên Bản 1.0.0

-
- - -
-

✅ Ứng Dụng Đã Hoàn Thành!

-

Bạn đã tích hợp 3 file HTML thành một ứng dụng web hoàn chỉnh. Ứng dụng hiện đã sẵn sàng để sử dụng và quản lý tài khoản của các dịch vụ/ứng dụng.

- -

🌟 Tính Năng Chính

-
-
- 📊 Dashboard - Xem tổng quan thống kê -
-
- 👥 Quản Tài Khoản - Thêm/Sửa/Xóa tài khoản -
-
- 🔧 Quản Ứng Dụng - Theo dõi các dịch vụ -
-
- 💾 Lưu Trữ - Dữ liệu an toàn trên trình duyệt -
-
- 📱 Responsive - Hoạt động trên mọi thiết bị -
-
- ⚡ Offline - Hoàn toàn offline, không cần internet -
-
-
- - -
-

🚀 Bắt Đầu Nhanh

-
    -
  1. Mở ứng dụng: Nhấp nút "Mở VaultSentinel" bên dưới hoặc mở file index.html
  2. -
  3. Khám phá: Sử dụng menu bên trái để chuyển giữa các trang
  4. -
  5. Thêm dữ liệu: Nhấp "Add Account" hoặc "Add New Application"
  6. -
  7. Quản lý: Chỉnh sửa hoặc xóa các mục theo nhu cầu
  8. -
  9. Tận hưởng: Tất cả dữ liệu được lưu tự động
  10. -
-
- - -
- -
-
🎯 Ứng Dụng Chính
-
-

Mở ứng dụng VaultSentinel để quản lý tài khoản và dịch vụ của bạn.

- Mở VaultSentinel → -
-
- - -
-
📖 Hướng Dẫn Nhanh
-
-

Hướng dẫn chi tiết cách sử dụng ứng dụng với các ví dụ thực tế.

- Xem Hướng Dẫn → -
-
- - -
-
📚 Tài Liệu Chi Tiết
-
-

Tài liệu đầy đủ về các tính năng, cách sử dụng, và tương lai phát triển.

- Đọc README → -
-
- - -
-
📋 Tóm Tắt Dự Án
-
-

Tóm tắt về các file được tạo, tính năng, và cấu trúc ứng dụng.

- Xem Tóm Tắt → -
-
- - -
-
✅ Bảng Kiểm Tra
-
-

Kiểm tra xem tất cả tính năng có được thiết lập đúng không.

- Xem Kiểm Tra → -
-
- - -
-
🛠️ Công Nghệ
-
-

- • HTML5 & CSS3
- • Tailwind CSS
- • JavaScript (ES6+)
- • localStorage API
- • Material Symbols -

-
-
-
- - -
-

📁 Cấu Trúc File

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileMô TảKích Thước
index.htmlFile HTML chính - Mở file này8.5 KB
app.jsLogic JavaScript chính32.8 KB
README.mdTài liệu hướng dẫn (Tiếng Việt)4.7 KB
GUIDE.htmlHướng dẫn nhanh dạng web13 KB
SUMMARY.mdTóm tắt dự án và tính năng5.2 KB
CHECK.htmlBảng kiểm tra tính năng7.5 KB
-
- - -
-

⚠️ Lưu Ý Quan Trọng

-
- 🔒 Bảo Mật: -
    -
  • Dữ liệu được lưu cục bộ trên trình duyệt của bạn
  • -
  • KHÔNG gửi dữ liệu đến máy chủ nào
  • -
  • Chỉ sử dụng trên máy tính được tin cậy
  • -
  • KHÔNG sử dụng cho dữ liệu nhạy cảm trong môi trường thực tế
  • -
  • Xóa cache trình duyệt sẽ mất ALL dữ liệu
  • -
-
-
- - -
-

❓ Câu Hỏi Thường Gặp

-

Q: Tôi phải cài đặt gì không?

-

A: Không! Chỉ cần mở file index.html trên trình duyệt. Ứng dụng không cần cài đặt hoặc backend.

- -

Q: Dữ liệu của tôi được lưu ở đâu?

-

A: Dữ liệu được lưu trong localStorage của trình duyệt. Mỗi trình duyệt/máy tính có storage riêng.

- -

Q: Ứng dụng có hoạt động offline không?

-

A: Có! Ứng dụng hoàn toàn offline. Lệnh gọi CDN lần đầu sẽ require internet, nhưng sau đó offline vẫn được.

- -

Q: Tôi có thể sao lưu dữ liệu không?

-

A: Hiện chưa có tính năng export/import. Bạn có thể dùng DevTools để export localStorage.

-
- - -
-

🆘 Hỗ Trợ

-

Nếu gặp vấn đề:

-
    -
  1. Kiểm tra Console trình duyệt (F12) để xem lỗi
  2. -
  3. Xóa cache và reload trang (Ctrl+Shift+R)
  4. -
  5. Thử trình duyệt khác (Chrome, Firefox, Edge, Safari)
  6. -
  7. Đọc README.md hoặc GUIDE.html để xem thêm
  8. -
-
- - - -
- -