Updates to sending user details

This commit is contained in:
admin 2025-08-03 13:26:20 -06:00
parent e488a23bfb
commit 532286217e
22 changed files with 1669 additions and 156 deletions

68
git-report.txt Normal file
View File

@ -0,0 +1,68 @@
e488a23 2025-08-01 | admin | few small changes to language on the admin page
5b673da 2025-08-01 | admin | A tonne more changes, including new nocodb admin section, search for database, code cleanups, and debugging
9fcaf48 2025-08-01 | admin | website updates
55cd626 2025-08-01 | admin | Data converter
0dacdfc 2025-07-31 | admin | udpated config to properly build for smtp
52d921c 2025-07-31 | admin | smtp integration and password recovery.
c0811de 2025-07-31 | admin | a few more dashboard updates
d775dea 2025-07-30 | admin | mobile friendliness
373018c 2025-07-30 | admin | anaylitics dashboard
7edc665 2025-07-30 | admin | square representations of apartments
0d7bdf0 2025-07-29 | admin | Updated apartment locations to stand out mor
dfe7c69 2025-07-28 | admin | some auth updates that got over written
8cebb56 2025-07-27 | admin | Fixed the input form modal to be above the other modals.
d711456 2025-07-27 | admin | Full update to map css
994440a 2025-07-27 | admin | Added apartment views and city of edmonton data import
5da24ae 2025-07-27 | admin | New site frontend updates, search, and general bug fixes
3b7d382 2025-07-24 | admin | Some udpates to tracking user inputs. Still not happy with it but functional so moving on
bb7032d 2025-07-24 | admin | A tonne of updates to how the system builds the view points in hopes of having a better mobile expereince
59ca237 2025-07-22 | admin | QR Code Maker update
dd416f8 2025-07-20 | admin | fixed the search float
54b9210 2025-07-19 | admin | new stuff
5bf87d4 2025-07-19 | admin | New search functionality
0088ffd 2025-07-19 | admin | few cosmetic updates
7989ea0 2025-07-18 | admin | added a move system for the pins
b98207b 2025-07-17 | admin | Fixed some menu bugs
6aae0fe 2025-07-17 | admin | added in the user managment section. Need to also do some updates to the admin menue and whatnot however itll get figured.
88b80bc 2025-07-16 | admin | bug fixes for shifts functionality
65c786d 2025-07-16 | admin | new system for address confrimation
ff3e1e8 2025-07-16 | admin | Added calendar view to the shifts
e056290 2025-07-16 | admin | updated the config.sh so that multiple changemakers can be run on each machine easier.
167b82f 2025-07-16 | admin | added shift titles to the shift signup sheets to make tracking easier and adding shifts easier
fb90f2a 2025-07-16 | admin | Config fixes for the services. yaml and a couple minor things about making it more url agnostic.
2c0c943 2025-07-16 | admin | config changes to better build map .env and updates to the login ui controls
0dd56c0 2025-07-16 | admin | Couple more updates to shiftcontroller to make it more robust
a5bd0e9 2025-07-16 | admin | Fixed bug for displaying sign ups for shifts
9e5b319 2025-07-13 | admin | Fixed bug with where maps presents
2b05b60 2025-07-11 | admin | debugged build precision values on decimal places inside nocodb
0878237 2025-07-11 | admin | Fixes to the map display and several other bugs
c29ad2d 2025-07-10 | admin | Shifts manager
5cba672 2025-07-10 | admin | updates to saving settings
2778b15 2025-07-09 | admin | map system updates
1236c6b 2025-07-09 | admin | Mpas manual and udpates to map view buttons for simpler workflow
34ef38a 2025-07-09 | admin | UI updates to better position map for building dots
d11837e 2025-07-09 | admin | Added in a password field for login. need to add encryption sometime
ab2e91e 2025-07-08 | admin | fixed the preview on moblie for the walk sheet
e31b770 2025-07-08 | admin | naming updates
de3b349 2025-07-08 | admin | documentation updates
56ab400 2025-07-07 | admin | map styling update
488bb99 2025-07-07 | admin | build nocodb udpate - makes new base on every run
c1f6f25 2025-07-06 | admin | okay bidirectional saving done
1ba3899 2025-07-06 | admin | final update for the map server omg
18de90f 2025-07-06 | admin | got config save working
5f39ce8 2025-07-06 | admin | more configs and readme updates.
c4ea519 2025-07-06 | admin | reste.sh updatae
ac01d92 2025-07-06 | admin | okay got to a much more stable state. Fixed race condtion at stat of files. Should be smooth salining for a bit now.
1fc8b52 2025-07-06 | admin | final round of updates. Still need to stabalize first load for the map, having issues for sure; longer load time
f4eefa1 2025-07-05 | admin | resolved most in browser errors and got maps stable. Next need to do some work on the save configuration stuff.
412ca36 2025-07-05 | admin | config.sh fix
776420b 2025-07-05 | admin | build shell script for NocoDB map data
77c3a32 2025-07-05 | admin | new maps admin feature
09c8e02 2025-07-05 | admin | start production updates
4b6acbd 2025-07-04 | admin | update so we can run more than one changemaker per machine
e9d5af3 2025-07-04 | admin | removed the cloudflare credentials and yml from up
d41bd87 2025-07-04 | admin | pushing updates before doing a reset on local machine.
ed0bd33 2025-07-04 | admin | Clean up
949be0b 2025-07-03 | admin | maps updates
7e65665 2025-07-03 | admin | Some updates to the start-production script and just general clean up
ea6e5f1 2025-07-02 | admin | a tonne of improvements! We got maps updaTed, a tonne of documentaiton done, and several small upgrades to hook logic and other things. Fixed the looping problem for mkdocs and claude is not integrated with coder; if people wanna have a ai anyway

View File

@ -2,6 +2,7 @@ const nocodbService = require('../services/nocodb');
const logger = require('../utils/logger'); const logger = require('../utils/logger');
const config = require('../config'); const config = require('../config');
const { sanitizeUser, extractId } = require('../utils/helpers'); const { sanitizeUser, extractId } = require('../utils/helpers');
const { sendLoginDetails } = require('../services/email');
class UsersController { class UsersController {
async getAll(req, res) { async getAll(req, res) {
@ -155,6 +156,47 @@ class UsersController {
}); });
} }
} }
async sendLoginDetails(req, res) {
try {
const userId = req.params.id;
if (!config.nocodb.loginSheetId) {
return res.status(500).json({
success: false,
error: 'Login sheet not configured'
});
}
// Get user data from database
const user = await nocodbService.getById(
config.nocodb.loginSheetId,
userId
);
if (!user) {
return res.status(404).json({
success: false,
error: 'User not found'
});
}
// Send login details email
await sendLoginDetails(user);
res.json({
success: true,
message: 'Login details sent successfully'
});
} catch (error) {
logger.error('Error sending login details:', error);
res.status(500).json({
success: false,
error: 'Failed to send login details'
});
}
}
} }
module.exports = new UsersController(); module.exports = new UsersController();

View File

@ -346,7 +346,7 @@ function setupEventListeners() {
} }
// User form submission // User form submission
const userForm = document.getElementById('user-form'); const userForm = document.getElementById('create-user-form');
if (userForm) { if (userForm) {
userForm.addEventListener('submit', createUser); userForm.addEventListener('submit', createUser);
} }
@ -1269,6 +1269,9 @@ function displayUsers(users) {
<td data-label="Created">${formattedDate}</td> <td data-label="Created">${formattedDate}</td>
<td data-label="Actions"> <td data-label="Actions">
<div class="user-actions"> <div class="user-actions">
<button class="btn btn-secondary send-login-btn" data-user-id="${userId}" data-user-email="${escapeHtml(user.email || user.Email)}">
Send Login Details
</button>
<button class="btn btn-danger delete-user-btn" data-user-id="${userId}" data-user-email="${escapeHtml(user.email || user.Email)}"> <button class="btn btn-danger delete-user-btn" data-user-id="${userId}" data-user-email="${escapeHtml(user.email || user.Email)}">
Delete Delete
</button> </button>
@ -1288,22 +1291,27 @@ function displayUsers(users) {
} }
function setupUserActionListeners() { function setupUserActionListeners() {
const tableBody = document.getElementById('users-table-body'); const container = document.querySelector('.users-list');
if (!tableBody) return; if (!container) return;
// Remove existing listeners by cloning the node // Remove existing event listeners by cloning the container
const newTableBody = tableBody.cloneNode(true); const newContainer = container.cloneNode(true);
tableBody.parentNode.replaceChild(newTableBody, tableBody); container.parentNode.replaceChild(newContainer, container);
// Get the updated reference // Get the updated reference
const updatedTableBody = document.getElementById('users-table-body'); const updatedContainer = document.querySelector('.users-list');
updatedTableBody.addEventListener('click', function(e) { updatedContainer.addEventListener('click', function(e) {
if (e.target.classList.contains('delete-user-btn')) { if (e.target.classList.contains('delete-user-btn')) {
const userId = e.target.getAttribute('data-user-id'); const userId = e.target.getAttribute('data-user-id');
const userEmail = e.target.getAttribute('data-user-email'); const userEmail = e.target.getAttribute('data-user-email');
console.log('Delete button clicked for user:', userId); console.log('Delete button clicked for user:', userId);
deleteUser(userId, userEmail); deleteUser(userId, userEmail);
} else if (e.target.classList.contains('send-login-btn')) {
const userId = e.target.getAttribute('data-user-id');
const userEmail = e.target.getAttribute('data-user-email');
console.log('Send login details button clicked for user:', userId);
sendLoginDetailsToUser(userId, userEmail);
} }
}); });
} }
@ -1333,13 +1341,40 @@ async function deleteUser(userId, userEmail) {
} }
} }
async function sendLoginDetailsToUser(userId, userEmail) {
if (!confirm(`Send login details to "${userEmail}"?`)) {
return;
}
try {
const response = await fetch(`/api/users/${userId}/send-login-details`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
}
});
const data = await response.json();
if (data.success) {
showStatus(`Login details sent to "${userEmail}" successfully`, 'success');
} else {
throw new Error(data.error || 'Failed to send login details');
}
} catch (error) {
console.error('Error sending login details:', error);
showStatus(`Failed to send login details: ${error.message}`, 'error');
}
}
async function createUser(e) { async function createUser(e) {
e.preventDefault(); e.preventDefault();
const email = document.getElementById('user-email').value.trim(); const email = document.getElementById('user-email').value.trim();
const password = document.getElementById('user-password').value; const password = document.getElementById('user-password').value;
const name = document.getElementById('user-name').value.trim(); const name = document.getElementById('user-name').value.trim();
const admin = document.getElementById('user-admin').checked; const admin = document.getElementById('user-is-admin').checked;
if (!email || !password) { if (!email || !password) {
showStatus('Email and password are required', 'error'); showStatus('Email and password are required', 'error');
@ -1382,7 +1417,7 @@ async function createUser(e) {
} }
function clearUserForm() { function clearUserForm() {
const form = document.getElementById('user-form'); const form = document.getElementById('create-user-form');
if (form) { if (form) {
form.reset(); form.reset();
showStatus('User form cleared', 'info'); showStatus('User form cleared', 'info');

View File

@ -8,6 +8,9 @@ router.get('/', usersController.getAll);
// Create new user // Create new user
router.post('/', usersController.create); router.post('/', usersController.create);
// Send login details to user
router.post('/:id/send-login-details', usersController.sendLoginDetails);
// Delete user // Delete user
router.delete('/:id', usersController.delete); router.delete('/:id', usersController.delete);

View File

@ -92,8 +92,41 @@ const sendPasswordRecovery = async (user) => {
} }
}; };
const sendLoginDetails = async (user) => {
try {
const baseUrl = config.isProduction ?
`https://map.${config.domain}` :
`http://localhost:${config.port}`;
const isAdmin = user.admin || user.Admin || false;
const variables = {
APP_NAME: process.env.APP_NAME || 'CMlite Map',
USER_NAME: user.Name || user.name || user.Email || user.email,
USER_EMAIL: user.Email || user.email,
PASSWORD: user.Password || user.password,
USER_ROLE: isAdmin ? 'Administrator' : 'User',
LOGIN_URL: `${baseUrl}/login.html`,
TIMESTAMP: new Date().toLocaleString()
};
const { html, text } = await emailTemplates.render('login-details', variables);
return await sendEmail({
to: user.Email || user.email,
subject: `Your Login Details - ${variables.APP_NAME}`,
text,
html
});
} catch (error) {
logger.error('Failed to send login details email:', error);
throw error;
}
};
module.exports = { module.exports = {
initializeEmailService, initializeEmailService,
sendEmail, sendEmail,
sendPasswordRecovery sendPasswordRecovery,
sendLoginDetails
}; };

View File

@ -0,0 +1,116 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Your Login Details</title>
<style>
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
line-height: 1.6;
color: #333;
max-width: 600px;
margin: 0 auto;
padding: 20px;
}
.container {
background-color: #f9f9f9;
border-radius: 8px;
padding: 30px;
border: 1px solid #e0e0e0;
}
.header {
text-align: center;
margin-bottom: 30px;
}
.logo {
color: #a02c8d;
font-size: 24px;
font-weight: bold;
}
.content {
background-color: white;
padding: 20px;
border-radius: 6px;
margin-bottom: 20px;
}
.credentials-box {
background-color: #f0f0f0;
padding: 15px;
border-radius: 4px;
margin: 20px 0;
border: 1px solid #ddd;
}
.credential-item {
margin: 10px 0;
}
.credential-label {
font-weight: bold;
display: inline-block;
width: 100px;
}
.credential-value {
font-family: monospace;
font-size: 16px;
color: #2c3e50;
}
.login-button {
display: inline-block;
background-color: #a02c8d;
color: white;
padding: 12px 24px;
text-decoration: none;
border-radius: 4px;
margin: 20px 0;
}
.footer {
text-align: center;
font-size: 12px;
color: #666;
margin-top: 30px;
}
.info {
color: #3498db;
font-size: 14px;
margin-top: 20px;
}
</style>
</head>
<body>
<div class="container">
<div class="header">
<div class="logo">{{APP_NAME}}</div>
</div>
<div class="content">
<h2>Your Login Details</h2>
<p>Hello {{USER_NAME}},</p>
<p>Here are your login credentials for {{APP_NAME}}:</p>
<div class="credentials-box">
<div class="credential-item">
<span class="credential-label">Email:</span>
<span class="credential-value">{{USER_EMAIL}}</span>
</div>
<div class="credential-item">
<span class="credential-label">Password:</span>
<span class="credential-value">{{PASSWORD}}</span>
</div>
<div class="credential-item">
<span class="credential-label">Role:</span>
<span class="credential-value">{{USER_ROLE}}</span>
</div>
</div>
<p>You can log in using the link below:</p>
<p style="text-align: center;">
<a href="{{LOGIN_URL}}" class="login-button">Login to {{APP_NAME}}</a>
</p>
<p class="info">💡 For security reasons, we recommend changing your password after your first login.</p>
</div>
<div class="footer">
<p>This email was sent from {{APP_NAME}} at {{TIMESTAMP}}</p>
<p>If you have any questions, please contact your administrator.</p>
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,17 @@
Login Details - {{APP_NAME}}
Hello {{USER_NAME}},
Here are your login credentials for {{APP_NAME}}:
Email: {{USER_EMAIL}}
Password: {{PASSWORD}}
Role: {{USER_ROLE}}
You can log in at: {{LOGIN_URL}}
For security reasons, we recommend changing your password after your first login.
---
This email was sent from {{APP_NAME}} at {{TIMESTAMP}}
If you have any questions, please contact your administrator.

View File

@ -62,7 +62,7 @@ Controller for aggregating and calculating dashboard statistics from locations a
# app/controllers/usersController.js # app/controllers/usersController.js
Controller for user management (list, create, delete users). Controller for user management (list, create, delete users, send login details via email).
# app/middleware/auth.js # app/middleware/auth.js
@ -98,7 +98,7 @@ Service for generating QR codes and handling QR-related logic.
# app/services/email.js # app/services/email.js
Service for sending emails via SMTP, including password recovery emails using nodemailer. Supports multiple SMTP providers and includes connection verification and error handling. Service for sending emails via SMTP, including password recovery emails and login details using nodemailer. Supports multiple SMTP providers and includes connection verification and error handling.
# app/services/emailTemplates.js # app/services/emailTemplates.js
@ -112,6 +112,14 @@ Plain text email template for password recovery notifications. Contains user-fri
HTML email template for password recovery notifications. Features responsive design with styled password display box and security warnings for better user experience. HTML email template for password recovery notifications. Features responsive design with styled password display box and security warnings for better user experience.
# app/templates/email/login-details.txt
Plain text email template for sending login credentials to users. Contains email, password, role, and login URL with security recommendations.
# app/templates/email/login-details.html
HTML email template for sending login credentials to users. Features responsive design with styled credentials display and login button for better user experience.
# app/utils/helpers.js # app/utils/helpers.js
Utility functions for geographic data, validation, and helpers used across the backend. Utility functions for geographic data, validation, and helpers used across the backend.

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

View File

@ -7,10 +7,10 @@
"stars_count": 0, "stars_count": 0,
"forks_count": 0, "forks_count": 0,
"open_issues_count": 8, "open_issues_count": 8,
"updated_at": "2025-08-01T10:32:33-06:00", "updated_at": "2025-08-01T15:14:12-06:00",
"created_at": "2025-05-28T14:54:59-06:00", "created_at": "2025-05-28T14:54:59-06:00",
"clone_url": "https://gitea.bnkops.com/admin/changemaker.lite.git", "clone_url": "https://gitea.bnkops.com/admin/changemaker.lite.git",
"ssh_url": "git@gitea.bnkops.com:admin/changemaker.lite.git", "ssh_url": "git@gitea.bnkops.com:admin/changemaker.lite.git",
"default_branch": "main", "default_branch": "main",
"last_build_update": "2025-08-01T10:32:33-06:00" "last_build_update": "2025-08-01T15:14:12-06:00"
} }

View File

@ -0,0 +1,74 @@
---
date: 2025-08-01
---
Alrighty yall, it was a wild month of development, and we have a lot to cover! Heres the latest on Changemaker Lite, including our new landing page, major updates to the map application, and a comprehensive overview of all changes made in the last month.
Campaigning is going! We have candidates working the system in the field, and were excited to see how it performs in real-world scenarios.
# Monthly Development Report August 2025
## Git Change Summary (JulyAugust 2025)
Below is a summary of all changes pushed to git in the last month:
- **Admin Panel & NocoDB Integration**: Major updates to the admin section, including a new NocoDB admin area, improved database search, and code cleanups.
- **Website & UI Updates**: Numerous updates to the website, including language tweaks, mobile friendliness, and new frontend features.
- **Shifts Management**: Comprehensive volunteer shift management system added, with calendar/grid views, admin controls, and real-time updates.
- **Authentication & User Management**: Enhanced login system, password recovery via SMTP, user management panel for admins, and role-based access control.
- **Map & Geocoding**: Improved map display, apartment views, geocoding integration, and address confirmation system.
- **Unified Search System**: Powerful search bar (Ctrl+K) for docs and address search, with real-time results, caching, and QR code generation.
- **Data Import & Conversion**: CSV data import with batch geocoding and visual progress, plus a new data converter tool.
- **Email & Notifications**: SMTP integration for email notifications and password recovery.
- **Performance & Bug Fixes**: Numerous bug fixes, code cleanups, and performance improvements across the stack.
- **Docker & Deployment**: Docker containerization, improved build scripts, and easier multi-instance deployment.
- **Documentation**: Expanded and updated documentation, including new manuals and guides.
For a detailed commit log, see `git-report.txt`.
---
## Overview of `lander.html`
The `lander.html` file is a modern, responsive landing page for Changemaker Lite, featuring:
- **Custom Theming**: Light/dark mode toggle with persistent user preference.
- **Sticky Header & Navigation**: Fixed header with smooth scroll and navigation links.
- **Hero Section**: Prominent introduction with call-to-action buttons.
- **Search Integration**: Inline MkDocs search with real-time results and keyboard shortcuts.
- **Feature Showcases**: Sections for problems, solutions, power tools, data ownership, pricing, integrations, testimonials, and live examples.
- **Responsive Design**: Mobile-friendly layout with adaptive grids and cards.
- **Animations**: Intersection observer for fade-in effects on cards and sections.
- **Video & Media**: Embedded video showcase and rich media support.
- **Footer**: Informative footer with links and contact info.
The page is styled with CSS variables for easy theming and includes scripts for search, theme switching, and smooth scrolling.
---
## New Features in Map (`README.md`)
The map application has received significant upgrades:
- **Interactive Map**: Real-time visualization with OpenStreetMap and Leaflet.js.
- **Unified Search**: Docs and address search in one bar, with keyboard shortcuts and smart caching.
- **Geolocation & Add Locations**: Real-time user geolocation and ability to add new locations directly from the map.
- **Auto-Refresh**: Map data auto-refreshes every 30 seconds.
- **Responsive & Mobile Ready**: Fully responsive design for all devices.
- **Secure API Proxy**: Protects credentials and secures API access.
- **Admin Panel**: System configuration, user management, and shift management for admins.
- **Walk Sheet Generator**: For door-to-door canvassing, with customizable titles and QR code integration.
- **Volunteer Shifts**: Calendar/grid views, signup/cancellation, admin shift creation, and real-time updates.
- **Role-Based Access**: Admin vs. user permissions throughout the app.
- **Email Notifications**: SMTP-based notifications and password recovery.
- **CSV Import & Geocoding**: Batch import with geocoding and progress tracking.
- **Dockerized Deployment**: Easy setup and scaling with Docker.
- **Open Source**: 100% open source, no proprietary dependencies.
**API Endpoints**: Comprehensive REST API for locations, shifts, authentication, admin, and geocoding, all with rate limiting and security features.
**Database Schema**: Auto-created tables for locations, users, settings, shifts, and signups, with detailed field definitions.
---
For more details, see the full `README.md` and explore the live application.

View File

@ -54,20 +54,6 @@ Your data belongs to you and your community. We build tools that let you own you
Real security comes from community control, not corporate promises. We integrate security culture practices into our technology design. Real security comes from community control, not corporate promises. We integrate security culture practices into our technology design.
## The Changemaker Difference
### Traditional Corporate Flow
```
Your Data → Corporate Server → Surveillance → Profit → Your Oppression
```
### Changemaker Flow
```
Your Data → Your Server → Your Community → Your Power → Liberation
```
### Why This Matters ### Why This Matters
When you control your technology infrastructure: When you control your technology infrastructure:
@ -90,7 +76,7 @@ Digital security culture asks: "Who controls the infrastructure where this infor
We believe in **community technology** - tools that: We believe in **community technology** - tools that:
- Are owned and controlled by the communities that use them - Are owned and controlled by the communities that use them
- Are designed with liberation politics from the ground up - Are designed with liberation politics from the ground up using free and open source software
- Prioritize care, consent, and collective power - Prioritize care, consent, and collective power
- Can be understood, modified, and improved by community members - Can be understood, modified, and improved by community members
@ -123,19 +109,6 @@ Real security comes from community control, not corporate promises. When you con
- You know exactly where your data is and who can see it - You know exactly where your data is and who can see it
- You can't be de-platformed or locked out of your own data - You can't be de-platformed or locked out of your own data
## Historical Context
### Learning from Past Struggles
Every liberation movement has had to solve the problem of secure communication and information sharing:
- **Underground Railroad** - Coded songs and safe houses
- **Labor Movement** - Secret meetings and encrypted telegrams
- **Civil Rights Movement** - CB radios and phone trees
- **LGBTQ+ Liberation** - Chosen families and community networks
The internet should expand these traditions, not replace them with corporate surveillance.
### The Surveillance Capitalism Trap ### The Surveillance Capitalism Trap
As Shoshana Zuboff documents in "The Age of Surveillance Capitalism," we're living through a new form of capitalism that extracts value from human experience itself. Political movements are particularly valuable targets because: As Shoshana Zuboff documents in "The Age of Surveillance Capitalism," we're living through a new form of capitalism that extracts value from human experience itself. Political movements are particularly valuable targets because:

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

View File

@ -7,10 +7,10 @@
"stars_count": 0, "stars_count": 0,
"forks_count": 0, "forks_count": 0,
"open_issues_count": 8, "open_issues_count": 8,
"updated_at": "2025-08-01T10:32:33-06:00", "updated_at": "2025-08-01T15:14:12-06:00",
"created_at": "2025-05-28T14:54:59-06:00", "created_at": "2025-05-28T14:54:59-06:00",
"clone_url": "https://gitea.bnkops.com/admin/changemaker.lite.git", "clone_url": "https://gitea.bnkops.com/admin/changemaker.lite.git",
"ssh_url": "git@gitea.bnkops.com:admin/changemaker.lite.git", "ssh_url": "git@gitea.bnkops.com:admin/changemaker.lite.git",
"default_branch": "main", "default_branch": "main",
"last_build_update": "2025-08-01T10:32:33-06:00" "last_build_update": "2025-08-01T15:14:12-06:00"
} }

View File

@ -18,6 +18,8 @@
<link rel="prev" href="../../03/blog-1/"> <link rel="prev" href="../../03/blog-1/">
<link rel="next" href="../../../08/01/3/">
<link rel="icon" href="../../../../../assets/favicon.png"> <link rel="icon" href="../../../../../assets/favicon.png">
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.6.15"> <meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.6.15">
@ -879,6 +881,22 @@ Changemaker Archive. <a href="https://docs.bnkops.com">Learn more</a>
</a> </a>
<a href="../../../08/01/3/" class="md-footer__link md-footer__link--next" aria-label="Next: 3">
<div class="md-footer__title">
<span class="md-footer__direction">
Next
</span>
<div class="md-ellipsis">
3
</div>
</div>
<div class="md-footer__button md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M4 11v2h12l-5.5 5.5 1.42 1.42L19.84 12l-7.92-7.92L10.5 5.5 16 11z"/></svg>
</div>
</a>
</nav> </nav>

File diff suppressed because it is too large Load Diff

View File

@ -770,6 +770,89 @@ Changemaker Archive. <a href="https://docs.bnkops.com">Learn more</a>
<article class="md-post md-post--excerpt"> <article class="md-post md-post--excerpt">
<header class="md-post__header"> <header class="md-post__header">
<div class="md-post__meta md-meta">
<ul class="md-meta__list">
<li class="md-meta__item">
<time datetime="2025-08-01 00:00:00+00:00">Aug 1, 2025</time></li>
<li class="md-meta__item">
3 min read
</li>
</ul>
</div>
</header>
<div class="md-post__content md-typeset">
<h2 id="3"><a class="toclink" href="../../2025/08/01/3/">3</a></h2>
<p>Alrighty yall, it was a wild month of development, and we have a lot to cover! Heres the latest on Changemaker Lite, including our new landing page, major updates to the map application, and a comprehensive overview of all changes made in the last month.</p>
<p>Campaigning is going! We have candidates working the system in the field, and were excited to see how it performs in real-world scenarios.</p>
<h2 id="monthly-development-report-august-2025"><a class="toclink" href="../../2025/08/01/3/#monthly-development-report-august-2025">Monthly Development Report August 2025</a></h2>
<h3 id="git-change-summary-julyaugust-2025"><a class="toclink" href="../../2025/08/01/3/#git-change-summary-julyaugust-2025">Git Change Summary (JulyAugust 2025)</a></h3>
<p>Below is a summary of all changes pushed to git in the last month:</p>
<ul>
<li><strong>Admin Panel &amp; NocoDB Integration</strong>: Major updates to the admin section, including a new NocoDB admin area, improved database search, and code cleanups.</li>
<li><strong>Website &amp; UI Updates</strong>: Numerous updates to the website, including language tweaks, mobile friendliness, and new frontend features.</li>
<li><strong>Shifts Management</strong>: Comprehensive volunteer shift management system added, with calendar/grid views, admin controls, and real-time updates.</li>
<li><strong>Authentication &amp; User Management</strong>: Enhanced login system, password recovery via SMTP, user management panel for admins, and role-based access control.</li>
<li><strong>Map &amp; Geocoding</strong>: Improved map display, apartment views, geocoding integration, and address confirmation system.</li>
<li><strong>Unified Search System</strong>: Powerful search bar (Ctrl+K) for docs and address search, with real-time results, caching, and QR code generation.</li>
<li><strong>Data Import &amp; Conversion</strong>: CSV data import with batch geocoding and visual progress, plus a new data converter tool.</li>
<li><strong>Email &amp; Notifications</strong>: SMTP integration for email notifications and password recovery.</li>
<li><strong>Performance &amp; Bug Fixes</strong>: Numerous bug fixes, code cleanups, and performance improvements across the stack.</li>
<li><strong>Docker &amp; Deployment</strong>: Docker containerization, improved build scripts, and easier multi-instance deployment.</li>
<li><strong>Documentation</strong>: Expanded and updated documentation, including new manuals and guides.</li>
</ul>
<p>For a detailed commit log, see <code>git-report.txt</code>.</p>
<hr />
<h3 id="overview-of-landerhtml"><a class="toclink" href="../../2025/08/01/3/#overview-of-landerhtml">Overview of <code>lander.html</code></a></h3>
<p>The <code>lander.html</code> file is a modern, responsive landing page for Changemaker Lite, featuring:</p>
<ul>
<li><strong>Custom Theming</strong>: Light/dark mode toggle with persistent user preference.</li>
<li><strong>Sticky Header &amp; Navigation</strong>: Fixed header with smooth scroll and navigation links.</li>
<li><strong>Hero Section</strong>: Prominent introduction with call-to-action buttons.</li>
<li><strong>Search Integration</strong>: Inline MkDocs search with real-time results and keyboard shortcuts.</li>
<li><strong>Feature Showcases</strong>: Sections for problems, solutions, power tools, data ownership, pricing, integrations, testimonials, and live examples.</li>
<li><strong>Responsive Design</strong>: Mobile-friendly layout with adaptive grids and cards.</li>
<li><strong>Animations</strong>: Intersection observer for fade-in effects on cards and sections.</li>
<li><strong>Video &amp; Media</strong>: Embedded video showcase and rich media support.</li>
<li><strong>Footer</strong>: Informative footer with links and contact info.</li>
</ul>
<p>The page is styled with CSS variables for easy theming and includes scripts for search, theme switching, and smooth scrolling.</p>
<hr />
<h3 id="new-features-in-map-readmemd"><a class="toclink" href="../../2025/08/01/3/#new-features-in-map-readmemd">New Features in Map (<code>README.md</code>)</a></h3>
<p>The map application has received significant upgrades:</p>
<ul>
<li><strong>Interactive Map</strong>: Real-time visualization with OpenStreetMap and Leaflet.js.</li>
<li><strong>Unified Search</strong>: Docs and address search in one bar, with keyboard shortcuts and smart caching.</li>
<li><strong>Geolocation &amp; Add Locations</strong>: Real-time user geolocation and ability to add new locations directly from the map.</li>
<li><strong>Auto-Refresh</strong>: Map data auto-refreshes every 30 seconds.</li>
<li><strong>Responsive &amp; Mobile Ready</strong>: Fully responsive design for all devices.</li>
<li><strong>Secure API Proxy</strong>: Protects credentials and secures API access.</li>
<li><strong>Admin Panel</strong>: System configuration, user management, and shift management for admins.</li>
<li><strong>Walk Sheet Generator</strong>: For door-to-door canvassing, with customizable titles and QR code integration.</li>
<li><strong>Volunteer Shifts</strong>: Calendar/grid views, signup/cancellation, admin shift creation, and real-time updates.</li>
<li><strong>Role-Based Access</strong>: Admin vs. user permissions throughout the app.</li>
<li><strong>Email Notifications</strong>: SMTP-based notifications and password recovery.</li>
<li><strong>CSV Import &amp; Geocoding</strong>: Batch import with geocoding and progress tracking.</li>
<li><strong>Dockerized Deployment</strong>: Easy setup and scaling with Docker.</li>
<li><strong>Open Source</strong>: 100% open source, no proprietary dependencies.</li>
</ul>
<p><strong>API Endpoints</strong>: Comprehensive REST API for locations, shifts, authentication, admin, and geocoding, all with rate limiting and security features.</p>
<p><strong>Database Schema</strong>: Auto-created tables for locations, users, settings, shifts, and signups, with detailed field definitions.</p>
<hr />
<p>For more details, see the full <code>README.md</code> and explore the live application.</p>
</div>
</article>
<article class="md-post md-post--excerpt">
<header class="md-post__header">
<div class="md-post__meta md-meta"> <div class="md-post__meta md-meta">
<ul class="md-meta__list"> <ul class="md-meta__list">
<li class="md-meta__item"> <li class="md-meta__item">

View File

@ -753,6 +753,89 @@ Changemaker Archive. <a href="https://docs.bnkops.com">Learn more</a>
<article class="md-post md-post--excerpt"> <article class="md-post md-post--excerpt">
<header class="md-post__header"> <header class="md-post__header">
<div class="md-post__meta md-meta">
<ul class="md-meta__list">
<li class="md-meta__item">
<time datetime="2025-08-01 00:00:00+00:00">Aug 1, 2025</time></li>
<li class="md-meta__item">
3 min read
</li>
</ul>
</div>
</header>
<div class="md-post__content md-typeset">
<h2 id="3"><a class="toclink" href="2025/08/01/3/">3</a></h2>
<p>Alrighty yall, it was a wild month of development, and we have a lot to cover! Heres the latest on Changemaker Lite, including our new landing page, major updates to the map application, and a comprehensive overview of all changes made in the last month.</p>
<p>Campaigning is going! We have candidates working the system in the field, and were excited to see how it performs in real-world scenarios.</p>
<h2 id="monthly-development-report-august-2025"><a class="toclink" href="2025/08/01/3/#monthly-development-report-august-2025">Monthly Development Report August 2025</a></h2>
<h3 id="git-change-summary-julyaugust-2025"><a class="toclink" href="2025/08/01/3/#git-change-summary-julyaugust-2025">Git Change Summary (JulyAugust 2025)</a></h3>
<p>Below is a summary of all changes pushed to git in the last month:</p>
<ul>
<li><strong>Admin Panel &amp; NocoDB Integration</strong>: Major updates to the admin section, including a new NocoDB admin area, improved database search, and code cleanups.</li>
<li><strong>Website &amp; UI Updates</strong>: Numerous updates to the website, including language tweaks, mobile friendliness, and new frontend features.</li>
<li><strong>Shifts Management</strong>: Comprehensive volunteer shift management system added, with calendar/grid views, admin controls, and real-time updates.</li>
<li><strong>Authentication &amp; User Management</strong>: Enhanced login system, password recovery via SMTP, user management panel for admins, and role-based access control.</li>
<li><strong>Map &amp; Geocoding</strong>: Improved map display, apartment views, geocoding integration, and address confirmation system.</li>
<li><strong>Unified Search System</strong>: Powerful search bar (Ctrl+K) for docs and address search, with real-time results, caching, and QR code generation.</li>
<li><strong>Data Import &amp; Conversion</strong>: CSV data import with batch geocoding and visual progress, plus a new data converter tool.</li>
<li><strong>Email &amp; Notifications</strong>: SMTP integration for email notifications and password recovery.</li>
<li><strong>Performance &amp; Bug Fixes</strong>: Numerous bug fixes, code cleanups, and performance improvements across the stack.</li>
<li><strong>Docker &amp; Deployment</strong>: Docker containerization, improved build scripts, and easier multi-instance deployment.</li>
<li><strong>Documentation</strong>: Expanded and updated documentation, including new manuals and guides.</li>
</ul>
<p>For a detailed commit log, see <code>git-report.txt</code>.</p>
<hr />
<h3 id="overview-of-landerhtml"><a class="toclink" href="2025/08/01/3/#overview-of-landerhtml">Overview of <code>lander.html</code></a></h3>
<p>The <code>lander.html</code> file is a modern, responsive landing page for Changemaker Lite, featuring:</p>
<ul>
<li><strong>Custom Theming</strong>: Light/dark mode toggle with persistent user preference.</li>
<li><strong>Sticky Header &amp; Navigation</strong>: Fixed header with smooth scroll and navigation links.</li>
<li><strong>Hero Section</strong>: Prominent introduction with call-to-action buttons.</li>
<li><strong>Search Integration</strong>: Inline MkDocs search with real-time results and keyboard shortcuts.</li>
<li><strong>Feature Showcases</strong>: Sections for problems, solutions, power tools, data ownership, pricing, integrations, testimonials, and live examples.</li>
<li><strong>Responsive Design</strong>: Mobile-friendly layout with adaptive grids and cards.</li>
<li><strong>Animations</strong>: Intersection observer for fade-in effects on cards and sections.</li>
<li><strong>Video &amp; Media</strong>: Embedded video showcase and rich media support.</li>
<li><strong>Footer</strong>: Informative footer with links and contact info.</li>
</ul>
<p>The page is styled with CSS variables for easy theming and includes scripts for search, theme switching, and smooth scrolling.</p>
<hr />
<h3 id="new-features-in-map-readmemd"><a class="toclink" href="2025/08/01/3/#new-features-in-map-readmemd">New Features in Map (<code>README.md</code>)</a></h3>
<p>The map application has received significant upgrades:</p>
<ul>
<li><strong>Interactive Map</strong>: Real-time visualization with OpenStreetMap and Leaflet.js.</li>
<li><strong>Unified Search</strong>: Docs and address search in one bar, with keyboard shortcuts and smart caching.</li>
<li><strong>Geolocation &amp; Add Locations</strong>: Real-time user geolocation and ability to add new locations directly from the map.</li>
<li><strong>Auto-Refresh</strong>: Map data auto-refreshes every 30 seconds.</li>
<li><strong>Responsive &amp; Mobile Ready</strong>: Fully responsive design for all devices.</li>
<li><strong>Secure API Proxy</strong>: Protects credentials and secures API access.</li>
<li><strong>Admin Panel</strong>: System configuration, user management, and shift management for admins.</li>
<li><strong>Walk Sheet Generator</strong>: For door-to-door canvassing, with customizable titles and QR code integration.</li>
<li><strong>Volunteer Shifts</strong>: Calendar/grid views, signup/cancellation, admin shift creation, and real-time updates.</li>
<li><strong>Role-Based Access</strong>: Admin vs. user permissions throughout the app.</li>
<li><strong>Email Notifications</strong>: SMTP-based notifications and password recovery.</li>
<li><strong>CSV Import &amp; Geocoding</strong>: Batch import with geocoding and progress tracking.</li>
<li><strong>Dockerized Deployment</strong>: Easy setup and scaling with Docker.</li>
<li><strong>Open Source</strong>: 100% open source, no proprietary dependencies.</li>
</ul>
<p><strong>API Endpoints</strong>: Comprehensive REST API for locations, shifts, authentication, admin, and geocoding, all with rate limiting and security features.</p>
<p><strong>Database Schema</strong>: Auto-created tables for locations, users, settings, shifts, and signups, with detailed field definitions.</p>
<hr />
<p>For more details, see the full <code>README.md</code> and explore the live application.</p>
</div>
</article>
<article class="md-post md-post--excerpt">
<header class="md-post__header">
<div class="md-post__meta md-meta"> <div class="md-post__meta md-meta">
<ul class="md-meta__list"> <ul class="md-meta__list">
<li class="md-meta__item"> <li class="md-meta__item">

View File

@ -888,39 +888,6 @@ Changemaker Archive. <a href="https://docs.bnkops.com">Learn more</a>
</ul> </ul>
</nav> </nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#the-changemaker-difference" class="md-nav__link">
<span class="md-ellipsis">
The Changemaker Difference
</span>
</a>
<nav class="md-nav" aria-label="The Changemaker Difference">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#traditional-corporate-flow" class="md-nav__link">
<span class="md-ellipsis">
Traditional Corporate Flow
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#changemaker-flow" class="md-nav__link">
<span class="md-ellipsis">
Changemaker Flow
</span>
</a>
</li> </li>
<li class="md-nav__item"> <li class="md-nav__item">
@ -1023,30 +990,6 @@ Changemaker Archive. <a href="https://docs.bnkops.com">Learn more</a>
</span> </span>
</a> </a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#historical-context" class="md-nav__link">
<span class="md-ellipsis">
Historical Context
</span>
</a>
<nav class="md-nav" aria-label="Historical Context">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#learning-from-past-struggles" class="md-nav__link">
<span class="md-ellipsis">
Learning from Past Struggles
</span>
</a>
</li> </li>
<li class="md-nav__item"> <li class="md-nav__item">
@ -1210,13 +1153,6 @@ Changemaker Archive. <a href="https://docs.bnkops.com">Learn more</a>
<p>Your data belongs to you and your community. We build tools that let you own your digital infrastructure completely.</p> <p>Your data belongs to you and your community. We build tools that let you own your digital infrastructure completely.</p>
<h4 id="security-culture">🔒 Security Culture<a class="headerlink" href="#security-culture" title="Permanent link">&para;</a></h4> <h4 id="security-culture">🔒 Security Culture<a class="headerlink" href="#security-culture" title="Permanent link">&para;</a></h4>
<p>Real security comes from community control, not corporate promises. We integrate security culture practices into our technology design.</p> <p>Real security comes from community control, not corporate promises. We integrate security culture practices into our technology design.</p>
<h2 id="the-changemaker-difference">The Changemaker Difference<a class="headerlink" href="#the-changemaker-difference" title="Permanent link">&para;</a></h2>
<h3 id="traditional-corporate-flow">Traditional Corporate Flow<a class="headerlink" href="#traditional-corporate-flow" title="Permanent link">&para;</a></h3>
<div class="language-text highlight"><pre><span></span><code><span id="__span-0-1"><a id="__codelineno-0-1" name="__codelineno-0-1" href="#__codelineno-0-1"></a>Your Data → Corporate Server → Surveillance → Profit → Your Oppression
</span></code></pre></div>
<h3 id="changemaker-flow">Changemaker Flow<a class="headerlink" href="#changemaker-flow" title="Permanent link">&para;</a></h3>
<div class="language-text highlight"><pre><span></span><code><span id="__span-1-1"><a id="__codelineno-1-1" name="__codelineno-1-1" href="#__codelineno-1-1"></a>Your Data → Your Server → Your Community → Your Power → Liberation
</span></code></pre></div>
<h3 id="why-this-matters">Why This Matters<a class="headerlink" href="#why-this-matters" title="Permanent link">&para;</a></h3> <h3 id="why-this-matters">Why This Matters<a class="headerlink" href="#why-this-matters" title="Permanent link">&para;</a></h3>
<p>When you control your technology infrastructure:</p> <p>When you control your technology infrastructure:</p>
<ul> <ul>
@ -1233,7 +1169,7 @@ Changemaker Archive. <a href="https://docs.bnkops.com">Learn more</a>
<p>We believe in <strong>community technology</strong> - tools that:</p> <p>We believe in <strong>community technology</strong> - tools that:</p>
<ul> <ul>
<li>Are owned and controlled by the communities that use them</li> <li>Are owned and controlled by the communities that use them</li>
<li>Are designed with liberation politics from the ground up</li> <li>Are designed with liberation politics from the ground up using free and open source software</li>
<li>Prioritize care, consent, and collective power</li> <li>Prioritize care, consent, and collective power</li>
<li>Can be understood, modified, and improved by community members</li> <li>Can be understood, modified, and improved by community members</li>
</ul> </ul>
@ -1255,16 +1191,6 @@ Changemaker Archive. <a href="https://docs.bnkops.com">Learn more</a>
<li>You know exactly where your data is and who can see it</li> <li>You know exactly where your data is and who can see it</li>
<li>You can't be de-platformed or locked out of your own data</li> <li>You can't be de-platformed or locked out of your own data</li>
</ul> </ul>
<h2 id="historical-context">Historical Context<a class="headerlink" href="#historical-context" title="Permanent link">&para;</a></h2>
<h3 id="learning-from-past-struggles">Learning from Past Struggles<a class="headerlink" href="#learning-from-past-struggles" title="Permanent link">&para;</a></h3>
<p>Every liberation movement has had to solve the problem of secure communication and information sharing:</p>
<ul>
<li><strong>Underground Railroad</strong> - Coded songs and safe houses</li>
<li><strong>Labor Movement</strong> - Secret meetings and encrypted telegrams </li>
<li><strong>Civil Rights Movement</strong> - CB radios and phone trees</li>
<li><strong>LGBTQ+ Liberation</strong> - Chosen families and community networks</li>
</ul>
<p>The internet should expand these traditions, not replace them with corporate surveillance.</p>
<h3 id="the-surveillance-capitalism-trap">The Surveillance Capitalism Trap<a class="headerlink" href="#the-surveillance-capitalism-trap" title="Permanent link">&para;</a></h3> <h3 id="the-surveillance-capitalism-trap">The Surveillance Capitalism Trap<a class="headerlink" href="#the-surveillance-capitalism-trap" title="Permanent link">&para;</a></h3>
<p>As Shoshana Zuboff documents in "The Age of Surveillance Capitalism," we're living through a new form of capitalism that extracts value from human experience itself. Political movements are particularly valuable targets because:</p> <p>As Shoshana Zuboff documents in "The Age of Surveillance Capitalism," we're living through a new form of capitalism that extracts value from human experience itself. Political movements are particularly valuable targets because:</p>
<ul> <ul>

File diff suppressed because one or more lines are too long

View File

@ -2,142 +2,146 @@
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"> <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url> <url>
<loc>https://cmlite.org/</loc> <loc>https://cmlite.org/</loc>
<lastmod>2025-08-01</lastmod> <lastmod>2025-08-02</lastmod>
</url> </url>
<url> <url>
<loc>https://cmlite.org/test/</loc> <loc>https://cmlite.org/test/</loc>
<lastmod>2025-08-01</lastmod> <lastmod>2025-08-02</lastmod>
</url> </url>
<url> <url>
<loc>https://cmlite.org/adv/</loc> <loc>https://cmlite.org/adv/</loc>
<lastmod>2025-08-01</lastmod> <lastmod>2025-08-02</lastmod>
</url> </url>
<url> <url>
<loc>https://cmlite.org/adv/ansible/</loc> <loc>https://cmlite.org/adv/ansible/</loc>
<lastmod>2025-08-01</lastmod> <lastmod>2025-08-02</lastmod>
</url> </url>
<url> <url>
<loc>https://cmlite.org/adv/vscode-ssh/</loc> <loc>https://cmlite.org/adv/vscode-ssh/</loc>
<lastmod>2025-08-01</lastmod> <lastmod>2025-08-02</lastmod>
</url> </url>
<url> <url>
<loc>https://cmlite.org/blog/</loc> <loc>https://cmlite.org/blog/</loc>
<lastmod>2025-08-01</lastmod> <lastmod>2025-08-02</lastmod>
</url> </url>
<url> <url>
<loc>https://cmlite.org/blog/2025/07/03/blog-1/</loc> <loc>https://cmlite.org/blog/2025/07/03/blog-1/</loc>
<lastmod>2025-08-01</lastmod> <lastmod>2025-08-02</lastmod>
</url> </url>
<url> <url>
<loc>https://cmlite.org/blog/2025/07/10/2/</loc> <loc>https://cmlite.org/blog/2025/07/10/2/</loc>
<lastmod>2025-08-01</lastmod> <lastmod>2025-08-02</lastmod>
</url>
<url>
<loc>https://cmlite.org/blog/2025/08/01/3/</loc>
<lastmod>2025-08-02</lastmod>
</url> </url>
<url> <url>
<loc>https://cmlite.org/build/</loc> <loc>https://cmlite.org/build/</loc>
<lastmod>2025-08-01</lastmod> <lastmod>2025-08-02</lastmod>
</url> </url>
<url> <url>
<loc>https://cmlite.org/build/map/</loc> <loc>https://cmlite.org/build/map/</loc>
<lastmod>2025-08-01</lastmod> <lastmod>2025-08-02</lastmod>
</url> </url>
<url> <url>
<loc>https://cmlite.org/build/server/</loc> <loc>https://cmlite.org/build/server/</loc>
<lastmod>2025-08-01</lastmod> <lastmod>2025-08-02</lastmod>
</url> </url>
<url> <url>
<loc>https://cmlite.org/build/site/</loc> <loc>https://cmlite.org/build/site/</loc>
<lastmod>2025-08-01</lastmod> <lastmod>2025-08-02</lastmod>
</url> </url>
<url> <url>
<loc>https://cmlite.org/config/</loc> <loc>https://cmlite.org/config/</loc>
<lastmod>2025-08-01</lastmod> <lastmod>2025-08-02</lastmod>
</url> </url>
<url> <url>
<loc>https://cmlite.org/config/cloudflare-config/</loc> <loc>https://cmlite.org/config/cloudflare-config/</loc>
<lastmod>2025-08-01</lastmod> <lastmod>2025-08-02</lastmod>
</url> </url>
<url> <url>
<loc>https://cmlite.org/config/coder/</loc> <loc>https://cmlite.org/config/coder/</loc>
<lastmod>2025-08-01</lastmod> <lastmod>2025-08-02</lastmod>
</url> </url>
<url> <url>
<loc>https://cmlite.org/config/map/</loc> <loc>https://cmlite.org/config/map/</loc>
<lastmod>2025-08-01</lastmod> <lastmod>2025-08-02</lastmod>
</url> </url>
<url> <url>
<loc>https://cmlite.org/config/mkdocs/</loc> <loc>https://cmlite.org/config/mkdocs/</loc>
<lastmod>2025-08-01</lastmod> <lastmod>2025-08-02</lastmod>
</url> </url>
<url> <url>
<loc>https://cmlite.org/how%20to/canvass/</loc> <loc>https://cmlite.org/how%20to/canvass/</loc>
<lastmod>2025-08-01</lastmod> <lastmod>2025-08-02</lastmod>
</url> </url>
<url> <url>
<loc>https://cmlite.org/manual/</loc> <loc>https://cmlite.org/manual/</loc>
<lastmod>2025-08-01</lastmod> <lastmod>2025-08-02</lastmod>
</url> </url>
<url> <url>
<loc>https://cmlite.org/manual/map/</loc> <loc>https://cmlite.org/manual/map/</loc>
<lastmod>2025-08-01</lastmod> <lastmod>2025-08-02</lastmod>
</url> </url>
<url> <url>
<loc>https://cmlite.org/phil/</loc> <loc>https://cmlite.org/phil/</loc>
<lastmod>2025-08-01</lastmod> <lastmod>2025-08-02</lastmod>
</url> </url>
<url> <url>
<loc>https://cmlite.org/phil/cost-comparison/</loc> <loc>https://cmlite.org/phil/cost-comparison/</loc>
<lastmod>2025-08-01</lastmod> <lastmod>2025-08-02</lastmod>
</url> </url>
<url> <url>
<loc>https://cmlite.org/services/</loc> <loc>https://cmlite.org/services/</loc>
<lastmod>2025-08-01</lastmod> <lastmod>2025-08-02</lastmod>
</url> </url>
<url> <url>
<loc>https://cmlite.org/services/code-server/</loc> <loc>https://cmlite.org/services/code-server/</loc>
<lastmod>2025-08-01</lastmod> <lastmod>2025-08-02</lastmod>
</url> </url>
<url> <url>
<loc>https://cmlite.org/services/gitea/</loc> <loc>https://cmlite.org/services/gitea/</loc>
<lastmod>2025-08-01</lastmod> <lastmod>2025-08-02</lastmod>
</url> </url>
<url> <url>
<loc>https://cmlite.org/services/homepage/</loc> <loc>https://cmlite.org/services/homepage/</loc>
<lastmod>2025-08-01</lastmod> <lastmod>2025-08-02</lastmod>
</url> </url>
<url> <url>
<loc>https://cmlite.org/services/listmonk/</loc> <loc>https://cmlite.org/services/listmonk/</loc>
<lastmod>2025-08-01</lastmod> <lastmod>2025-08-02</lastmod>
</url> </url>
<url> <url>
<loc>https://cmlite.org/services/map/</loc> <loc>https://cmlite.org/services/map/</loc>
<lastmod>2025-08-01</lastmod> <lastmod>2025-08-02</lastmod>
</url> </url>
<url> <url>
<loc>https://cmlite.org/services/mini-qr/</loc> <loc>https://cmlite.org/services/mini-qr/</loc>
<lastmod>2025-08-01</lastmod> <lastmod>2025-08-02</lastmod>
</url> </url>
<url> <url>
<loc>https://cmlite.org/services/mkdocs/</loc> <loc>https://cmlite.org/services/mkdocs/</loc>
<lastmod>2025-08-01</lastmod> <lastmod>2025-08-02</lastmod>
</url> </url>
<url> <url>
<loc>https://cmlite.org/services/n8n/</loc> <loc>https://cmlite.org/services/n8n/</loc>
<lastmod>2025-08-01</lastmod> <lastmod>2025-08-02</lastmod>
</url> </url>
<url> <url>
<loc>https://cmlite.org/services/nocodb/</loc> <loc>https://cmlite.org/services/nocodb/</loc>
<lastmod>2025-08-01</lastmod> <lastmod>2025-08-02</lastmod>
</url> </url>
<url> <url>
<loc>https://cmlite.org/services/postgresql/</loc> <loc>https://cmlite.org/services/postgresql/</loc>
<lastmod>2025-08-01</lastmod> <lastmod>2025-08-02</lastmod>
</url> </url>
<url> <url>
<loc>https://cmlite.org/services/static-server/</loc> <loc>https://cmlite.org/services/static-server/</loc>
<lastmod>2025-08-01</lastmod> <lastmod>2025-08-02</lastmod>
</url> </url>
<url> <url>
<loc>https://cmlite.org/blog/archive/2025/</loc> <loc>https://cmlite.org/blog/archive/2025/</loc>
<lastmod>2025-08-01</lastmod> <lastmod>2025-08-02</lastmod>
</url> </url>
</urlset> </urlset>

Binary file not shown.