Files
eatme/gscript/Setup.js
Michal Pemcak 04e2f83c29 Scrub personal emails from example/reference files before going public
.env.example and gscript/Setup.js (the original Apps Script reference)
had real email addresses hardcoded as examples.
2026-08-16 18:41:11 +02:00

128 lines
3.9 KiB
JavaScript

function setupSystem() {
const props = PropertiesService.getScriptProperties();
let id = props.getProperty('DB_SPREADSHEET_ID');
let ss;
if (id) {
ss = SpreadsheetApp.openById(id);
} else {
ss = SpreadsheetApp.create('MeStaff Database');
props.setProperty('DB_SPREADSHEET_ID', ss.getId());
}
Object.keys(CFG.SHEETS).forEach(k => {
const name = CFG.SHEETS[k];
let s = ss.getSheetByName(name);
if (!s) s = ss.insertSheet(name);
const headers = HEADERS[k];
if (s.getLastRow() === 0) s.getRange(1,1,1,headers.length).setValues([headers]);
s.setFrozenRows(1);
s.getRange(1,1,1,headers.length).setFontWeight('bold');
});
const defaultSheet = ss.getSheetByName('Sheet1') || ss.getSheetByName('List1');
if (defaultSheet && Object.values(CFG.SHEETS).indexOf(defaultSheet.getName()) === -1) {
ss.deleteSheet(defaultSheet);
}
if (!props.getProperty('PASSWORD_PEPPER')) {
props.setProperty('PASSWORD_PEPPER', Utilities.getUuid() + Utilities.getUuid());
}
seedSettings_();
return {ok:true, spreadsheetId:ss.getId(), url:ss.getUrl()};
}
function seedSettings_() {
const current = rows_(CFG.SHEETS.SETTINGS);
const map = {};
current.forEach(r => map[r.key] = r.value);
const defaults = {
APP_NAME: 'MeStaff',
CURRENCY: 'CZK',
TIMEZONE: CFG.TZ,
NIGHT_START: '22:00',
NIGHT_END: '06:00'
};
Object.keys(defaults).forEach(k => {
if (map[k] === undefined) append_(CFG.SHEETS.SETTINGS, {key:k, value:defaults[k]});
});
}
function seedFirstAdmin(email, firstName, lastName) {
email = emailNorm_(email);
if (!email) throw new Error('Zadej e-mail.');
const lock = LockService.getScriptLock();
lock.waitLock(10000);
try {
let company = findOne_(CFG.SHEETS.COMPANIES, r => r.active === true || String(r.active).toUpperCase() === 'TRUE');
if (!company) {
company = {company_id:'COMPANY_MAIN', name:'Hlavní společnost', ico:'', active:true};
append_(CFG.SHEETS.COMPANIES, company);
}
let loc = findOne_(CFG.SHEETS.LOCATIONS, r => String(r.company_id) === String(company.company_id));
if (!loc) {
loc = {location_id:'LOCATION_MAIN', company_id:company.company_id, name:'Hlavní provozovna', active:true};
append_(CFG.SHEETS.LOCATIONS, loc);
}
let emp = findOne_(CFG.SHEETS.EMPLOYEES, r => emailNorm_(r.email) === email);
if (!emp) {
emp = {
employee_id: uuid_('EMP'),
first_name:firstName || 'Admin',
last_name:lastName || '',
email,
company_id:company.company_id,
location_id:loc.location_id,
position:'Administrátor',
employment_type:'',
terminal_pin:'',
start_date:isoDate_(now_()),
end_date:'',
active:true
};
append_(CFG.SHEETS.EMPLOYEES, emp);
}
let user = findOne_(CFG.SHEETS.USERS, r => emailNorm_(r.email) === email);
if (!user) {
user = {
user_id:uuid_('USR'),
email,
role:'ADMIN',
employee_id:emp.employee_id,
password_salt:'',
password_hash:'',
active:true,
created_at:now_(),
last_login:''
};
append_(CFG.SHEETS.USERS, user);
}
return {ok:true, email, message:'Admin založen. Teď použij „Aktivovat účet“ na přihlašovací stránce.'};
} finally {
lock.releaseLock();
}
}
function createSystemTriggers() {
ScriptApp.getProjectTriggers().forEach(t => {
if (['nightlyMaintenance','monthlyMaintenance'].includes(t.getHandlerFunction())) {
ScriptApp.deleteTrigger(t);
}
});
ScriptApp.newTrigger('nightlyMaintenance')
.timeBased().everyDays(1).atHour(3).inTimezone(CFG.TZ).create();
ScriptApp.newTrigger('monthlyMaintenance')
.timeBased().onMonthDay(1).atHour(4).inTimezone(CFG.TZ).create();
return {ok:true};
}
function createMyAdmin() {
return seedFirstAdmin(
'owner@example.com',
'First',
'Last'
);
}