Incremental Commit to see WTF I was doing.

This commit is contained in:
max committed 2025-09-14 19:13:47 +00:00
1 parent 276a72b4ce
commit 0b77b0516d
35 files changed
+774 -47

No files matched your search

+62
View File
@@ -0,0 +1,62 @@
echo '-------'
echo 'Starting Database Restore'
echo '-------'
#get Latest database backup
# Unzip File
# gzip -dk file.gz
source ~/.env
echo "$PROD_DB_PASS"
BACKUPDIR="/home/mab/databaseBackupSolidScribe"
mkdir -p $BACKUPDIR
cd $BACKUPDIR
# -t sort by modification time, newest first
# -A --almost-all, do not list implied . and ..
LASTZIPPEDFILE=$(ls -At *.gz | head -n1)
# -k keep file after unzip
# -d Decompress
# -v verbose
echo "Unzipping $LASTZIPPEDFILE"
gunzip -dkv $LASTZIPPEDFILE
BACKUPFILE=$(ls -At *.sql | head -n1)
#Fix to replace incompatible DB type
echo "Updating table name in -> $BACKUPFILE"
#sed -i $BACKUPFILE -e 's/utf8mb4_0900_ai_ci/utf8mb4_unicode_ci/g'
#Fix encoding for dev DB and exclude system tables
# sed -i 's/utf8mb4_0900_ai_ci/utf8mb4_general_ci/g' $BACKUPFILE
# sed -r '/INSERT INTO `(sys|mysql)`/d' $BACKUPFILE > $BACKUPFILE
#echo "Removing and syncing static files"
#rm -r /home/mab/ss/staticFiles/*
#rsync -e 'ssh -p 13328' -hazC --update [email protected]:/home/mab/pi/staticFiles /home/mab/ss/
echo "Updating Database"
mysql -u root --password="$PROD_DB_PASS" < $BACKUPFILE
## Optimize Database Tables
# mysqlcheck --all-databases
mysqlcheck --all-databases -o -u root --password="$PROD_DB_PASS" #--silent
# mysqlcheck --all-databases --auto-repair
# mysqlcheck --all-databases --analyze
# Fix an issues with DB after messing around with it
mysql_upgrade -u root --password="$PROD_DB_PASS"
#clean up extracted and modified SQL dumps
rm *.sql
echo '-------'
echo "Applied Prod database to Dev. LastFile: $BACKUPFILE"
echo '-------'
+3 -5
View File
@@ -1,5 +1,3 @@
#!/bin/bash
echo '-------'
echo 'Starting Database Restore'
echo '-------'
@@ -12,7 +10,7 @@ echo '-------'
BACKUPDIR="/home/mab/databaseBackupSolidScribe"
#DEVDBPASS="Crama!Lama*Jamma###88383!!!!!345345956245i"
#DEVDBPASS="RootPass1234!"
DEVDBPASS="ReallySecureRootPass123!"
DEVDBPASS="LetsKeepOut69FatHorses!"
# LazaLinga&33Can't!Do!That34
cd $BACKUPDIR
@@ -39,14 +37,14 @@ sed -r '/INSERT INTO `(sys|mysql)`/d' $BACKUPFILE > $BACKUPFILE
echo "Removing and syncing static files"
rm -r /home/mab/ss/staticFiles/*
rsync -e 'ssh -p 13328' -hazC --update mab@solidscribe.com:/home/mab/pi/staticFiles /home/mab/ss/
rsync -e 'ssh -p 13328' -hazC --update mab@45.79.41.75:/home/mab/pi/staticFiles /home/mab/ss/
echo "Updating Database"
mysql -u root --password="$DEVDBPASS" < $BACKUPFILE
## Optimize Database Tables
# mysqlcheck --all-databases
mysqlcheck --all-databases -o -u root --password="$DEVDBPASS" --silent
mysqlcheck --all-databases -o -u root --password="$DEVDBPASS" #--silent
# mysqlcheck --all-databases --auto-repair
# mysqlcheck --all-databases --analyze
+4 -4
View File
@@ -1,7 +1,7 @@
#!/bin/bash
#!/usr/bin/env bash
# Take all variables in .env and turn them into local variables for this script
source ~/.env
source /home/mab/.env
BACKUPDIR="/home/mab/databaseBackupSolidScribe"
@@ -9,7 +9,7 @@ mkdir -p $BACKUPDIR
cd $BACKUPDIR
NOW=$(date +"%Y-%m-%d_%H-%M")
ssh [email protected] -p 13328 "mysqldump --all-databases --single-transaction --user root -p$PROD_DB_PASS" > "backup-$NOW.sql"
mysqldump --all-databases --single-transaction --user root --password="$PROD_DB_PASS" > "backup-$NOW.sql"
gzip "backup-$NOW.sql"
# cp "backup-$NOW.sql" "/mnt/Windows Data/DatabaseBackups/backup-$NOW.sql"
@@ -17,7 +17,7 @@ gzip "backup-$NOW.sql"
echo "Database Backup Complete on $NOW"
# Delete all but last 8 files
ls -tp | grep -v '/$' | tail -n +9 | tr '\n' '\0' | xargs -0 rm --
#ls -tp | grep -v '/$' | tail -n +9 | tr '\n' '\0' | xargs -0 rm -f --
##
# Restore DB
+2 -2
View File
@@ -18,14 +18,14 @@ tar -czf release.tar.gz server node_modules client/dist staticFiles/assets
#send compressed release to remote machine
echo -e "\e[32m\nMoving compressed release to production... \n\e[0m"
rsync -e 'ssh -p 13328' -havzC --update release.tar.gz mab@solidscribe.com:/home/mab/pi/
rsync -e 'ssh -p 13328' -havzC --update release.tar.gz mab@45.79.41.75:/home/mab/pi/
# Remove Release from local after its been uploaded
rm release.tar.gz
#uncompress release on server
echo -e "\e[32m\nExtracting release on production... \n\e[0m"
ssh mab@solidscribe.com -p 13328 "cd /home/mab/pi/; rm -r server node_modules client; tar -xzf *.tar.gz --overwrite; rm *.tar.gz; pm2 reload all"
ssh mab@45.79.41.75 -p 13328 "cd /home/mab/pi/; rm -r server node_modules client; tar -xzf *.tar.gz --overwrite; rm *.tar.gz; pm2 reload all"
#Congratulate how awesome you are
echo -e "\e[32m\nRelease Complete! Nice Work! \n\e[0m"
+10 -6
View File
@@ -3547,9 +3547,9 @@
}
},
"node_modules/caniuse-lite": {
"version": "1.0.30001418",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001418.tgz",
"integrity": "sha512-oIs7+JL3K9JRQ3jPZjlH6qyYDp+nBTCais7hjh0s+fuBwufc7uZ7hPYMXrDOJhV360KGMTcczMRObk0/iMqZRg==",
"version": "1.0.30001651",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001651.tgz",
"integrity": "sha512-9Cf+Xv1jJNe1xPZLGuUXLNkE1BoDkqRqYyFJ9TDYSqhduqA4hu4oR9HluGoWYQC/aj8WHjsGVV+bwkh0+tegRg==",
"dev": true,
"funding": [
{
@@ -3559,6 +3559,10 @@
{
"type": "tidelift",
"url": "https://tidelift.com/funding/github/npm/caniuse-lite"
},
{
"type": "github",
"url": "https://github.com/sponsors/ai"
}
]
},
@@ -12823,9 +12827,9 @@
}
},
"caniuse-lite": {
"version": "1.0.30001418",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001418.tgz",
"integrity": "sha512-oIs7+JL3K9JRQ3jPZjlH6qyYDp+nBTCais7hjh0s+fuBwufc7uZ7hPYMXrDOJhV360KGMTcczMRObk0/iMqZRg==",
"version": "1.0.30001651",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001651.tgz",
"integrity": "sha512-9Cf+Xv1jJNe1xPZLGuUXLNkE1BoDkqRqYyFJ9TDYSqhduqA4hu4oR9HluGoWYQC/aj8WHjsGVV+bwkh0+tegRg==",
"dev": true
},
"case-sensitive-paths-webpack-plugin": {
Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 799 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

@@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M8.00251 14.9297L0 1.07422H6.14651L8.00251 4.27503L9.84583 1.07422H16L8.00251 14.9297Z" fill="black"/>
</svg>

After

Width:  |  Height:  |  Size: 215 B

+2 -1
View File
@@ -9,7 +9,8 @@
<link rel="shortcut icon" href="/api/static/assets/favicon.ico" type="image/x-icon"/>
<meta name="theme-color" content="#000" />
<link rel="manifest" href="/api/static/assets/manifest.json">
<!-- Manifest is generated per page -->
<!-- <link rel="manifest" href="/api/static/assets/manifest.json"> -->
<title>Solid Scribe - An easy, encrypted Note App</title>
<!-- <title><%= htmlWebpackPlugin.options.title %></title> -->
+79 -11
View File
@@ -1,7 +1,7 @@
<template>
<div id="app" :class="{ 'night-mode':($store.getters.getIsNightMode == 2) }">
<div class="ui container" v-if="showFakeSite">
<!-- <div class="ui container" v-if="showFakeSite">
<div class="ui basic very padded segment">
<div class="ui inverted red segment">
<h1>WARNING - False site detected</h1>
@@ -11,7 +11,7 @@
<h2>You will be redirected to the correct domain in {{redirectSeconds}}</h2>
</div>
</div>
</div>
</div> -->
<div class="auth-block" v-if="requireAuth">
<div class="ui raised inverted segment">
@@ -82,6 +82,74 @@ export default {
// - Gets new session tokens from server and uses them in app
beforeCreate: function(){
const root = 'https://www.solidscribe.com'
// const root = 'https://192.168.1.164'
const manifest = {
"theme_color":"#000",
"background_color": "#000",
"description": "Take Notes",
"display_override": ["fullscreen", "minimal-ui"],
"display": "standalone",
"icons": [
{
"src": root+"/api/static/assets/logo.png",
"sizes": "495x495",
"type": "image/png",
"purpose": "any"
},
{
"src": root+"/api/static/assets/maskable_icon.png",
"sizes": "826x826",
"type": "image/png",
"purpose": "maskable"
}
],
"screenshots" : [
{
"src": root+"/api/static/assets/lightmode.png",
"sizes": "1000x1080",
"type": "image/png"
},
{
"src": root+"/api/static/assets/darkmode.png",
"sizes": "1000x1081",
"type": "image/png"
}
],
"shortcuts" : [
{
"name": "Files & Links",
"url": " /attachments",
"description": "All Note files and links",
"icons": [{
"src": root+"/api/static/assets/icon1.png",
"sizes": "96x96",
"type": "image/png"
}]
},
{
"name": "Metric Track",
"url": "/metrictrack",
"description": "Metric Tracking",
"icons": [{
"src": root+"/api/static/assets/icon2.png",
"sizes": "96x96",
"type": "image/png"
}]
}
],
"name": "Solid Scribe",
"short_name": "Solid Scribe",
"author": "Max",
"scope": root,
"start_url": window.location.href
}
const link = document.createElement('link')
link.rel = 'manifest'
link.href = `data:application/json;base64,${btoa(JSON.stringify(manifest))}`
document.head.appendChild(link)
//Before all requests going out
axios.interceptors.request.use(
(config) => {
@@ -173,15 +241,15 @@ export default {
mounted: function(){
const isDev = process.env['NODE_ENV'] == 'development'
if(window.location.hostname.toLowerCase().replace('www.','') != "solidscribe.com" && !isDev){
this.showFakeSite = true
setInterval(() => {
this.redirectSeconds--
if(this.redirectSeconds == 0){
window.location.href = 'https://www.solidscribe.com'
}
}, 1000)
}
// if(window.location.hostname.toLowerCase().replace('www.','') != "solidscribe.com" && !isDev){
// this.showFakeSite = true
// setInterval(() => {
// this.redirectSeconds--
// if(this.redirectSeconds == 0){
// window.location.href = 'https://www.solidscribe.com'
// }
// }, 1000)
// }
//Update totals for entire app on event
this.$io.on('update_counts', () => {
+31 -4
View File
@@ -1068,6 +1068,10 @@
},
loadNoteNextFromServer(){
if(this.statusText != 'saved'){
return
}
clearTimeout(this.reloadNoteDebounce)
this.reloadNoteDebounce = setTimeout(() => {
@@ -1075,13 +1079,27 @@
// this.setText('')
//Focus Regained on Note, check for update
console.log('Ajax Call to /api/note/get')
axios.post('/api/note/get', { 'noteId': this.noteid })
.then(response => {
this.setupLoadedNoteData(response)
// Skip note update if it didn't change.
const newNoteHash = this.hashString( response.data.text )
if(newNoteHash == this.lastNoteHash){
console.log('Skipping any changes. Notes match')
return
}
//Manually set squire text to show
this.setText(this.noteText)
this.setupLoadedNoteData(response)
//Manually set squire text
const editorElement = document.getElementById('squire-id')
editorElement.innerHTML = response.data.text
this.$nextTick(() => {
this.restoreCaretPosition()
.catch(e => console.log(e) )
})
})
@@ -1098,6 +1116,7 @@
//If user leaves page then returns to page, reload the first batch
if(checkForUpdateTimeout){
console.log('Focused then unfocused for greater than 3 seconds. Checking with server.')
this.loadNoteNextFromServer()
this.lastInteractionTimestamp = now
}
@@ -1185,10 +1204,11 @@
this.diffsApplied = diffSinceLastUpdate.length
// console.log('Got Diffs Total -> ', diffSinceLastUpdate)
}
// console.log(diffSinceLastUpdate)
console.log(diffSinceLastUpdate)
this.patchText(diffSinceLastUpdate)
.then(() => {
this.restoreCaretPosition()
.catch(e => console.log(e) )
})
})
@@ -1197,11 +1217,16 @@
this.patchText([incomingDiff])
.then(() => {
this.restoreCaretPosition()
.catch(e => console.log(e) )
})
})
this.$io.on('new_note_text_saved', ({noteId, hash}) => {
if(this.statusText != 'saved'){
return
}
const sameIdCheck = (this.idleNote && this.noteid == noteId)
const differentHashCheck = (hash != this.lastNoteHash)
@@ -1235,6 +1260,8 @@
this.lastRange = this.generateSelector(element)
this.startOffset = parseInt(event.range.startOffset) || 0
console.log('Save Range ', [element, this.lastRange, this.startOffset])
return
},
restoreCaretPosition(){
+7 -7
View File
@@ -377,13 +377,13 @@ const SquireButtonFunctions = {
// this.diffNoteText = this.editor._getHTML()
//Make sure all list items have draggable property
let container = document.getElementById('squire-id')
let listItems = container.getElementsByTagName('li')
for(let itemIndex in listItems){
// console.log(listItems[itemIndex])
// listItems[itemIndex].setAttribute('draggable','true')
}
// console.log(listItems)
// let container = document.getElementById('squire-id')
// let listItems = container.getElementsByTagName('li')
// for(let itemIndex in listItems){
// // console.log(listItems[itemIndex])
// // listItems[itemIndex].setAttribute('draggable','true')
// }
// // console.log(listItems)
},
getText(){
+297
View File
@@ -0,0 +1,297 @@
<style>
.calendar {
width: 300px;
height: 400px;
display: inline-block;
}
.day {
width: 40px;
height: 40px;
border: 1px solid var(--border_color);
display: inline-block;
text-align: center;
font-size: 1.2em;
cursor: pointer;
}
.today {
font-weight: bold;
}
.day ~ .active {
background-color: var(--main-accent);
color: var(--body_bg_color);
}
.day ~ .has-data {
outline: #07f4f4;
outline-style: none;
outline-width: medium;
outline-style: none;
outline-offset: -4px;
outline-style: solid;
outline-width: 2px;
}
</style>
<template>
<div class="squire-box">
<h3>Cycle Tracking Beta
<span v-on:click="deleteData()">
<i class="clickable trash icon"></i>
</span>
</h3>
<div class="calendar">
<p>{{calendar.monthName}}, {{calendar.year}}</p>
<div v-for="day in calendar.weekdays" class="day">
{{ day }}
</div>
<div v-for="day in calendar.days" class="day"
:class="{
'today':day == calendar.today,
'active':dateCode == `${day}.${calendar.month}.${calendar.year}`,
'has-data':cycleData[`${day}.${calendar.month}.${calendar.year}`],
}"
v-on:click="openDayData(`${day}.${calendar.month}.${calendar.year}`)">
{{ day }}
</div>
</div>
<div class="ui form">
<h3><input type="text" v-model="dateCode" v-on:keypress.enter="openDayData(dateCode)"></h3>
<div class="field" v-for="field in fields">
<label>{{ field.label }}</label>
<div v-for="(value, key) in openDay">
<!-- float -->
<div v-if="field.type == 'float' && field.id == key" class="ui left icon input">
<input type="text" :placeholder="field.label" v-on:keyup="e => saveField(field.id, e.target.value)" :value="value">
<i class="thermometer half icon"></i>
</div>
<!-- range -->
<div v-if="field.type == 'range' && field.id == key">
<div :class="{green:(value == 1)}" v-on:click="saveField(field.id, 1)" class="ui button">1</div>
<div :class="{green:(value == 2)}" v-on:click="saveField(field.id, 2)" class="ui button">2</div>
<div :class="{green:(value == 3)}" v-on:click="saveField(field.id, 3)" class="ui button">3</div>
<div :class="{green:(value == 4)}" v-on:click="saveField(field.id, 4)" class="ui button">4</div>
<div :class="{green:(value == 5)}" v-on:click="saveField(field.id, 5)" class="ui button">5</div>
</div>
<!-- text area -->
<div v-if="field.type == 'text' && field.id == key">
<textarea rows="3" v-on:keyup="e => saveField(field.id, e.target.value)">
{{ value }}
</textarea>
</div>
</div>
</div>
<div class="ui green save button" v-on:click="saveDayData">
Save
</div>
</div>
</div>
</template>
<script>
import axios from 'axios'
export default {
name: 'CycleTracking',
components: {
'logo':require('@/components/LogoComponent.vue').default,
},
data () {
return {
appWorkingDate: null,
fields:[],
defaultFields:[
{'type':'float','label':'Basil Temp', 'id':'BT'},
{'type':'range','label':'Cervical Mucus', 'id':'CM'},
{'type':'text','label':'Notes', 'id':'NO'},
],
cycleData: {},
dateCode: null,
openDay: [],
calendar: {
monthName: '',
month: '',
year: '',
days: [],
weekdays: ['S','M','T','W','T','F','S'],
today: 0,
},
}
},
beforeCreate() {
// Perform Login check
this.$parent.loginGateway()
},
mounted(){
if(!this.$store.getters.getLoggedIn){
return
}
// setup date code
// day - month - year
const now = new Date()
this.appWorkingDate = now
const dateSetup = [
now.getDate(), // 1-31 (Day)
now.getMonth()+1, // 0-11 (Month)
now.getFullYear(), // 1888-2022 (Year)
]
this.dateCode = dateSetup.join('.')
this.setupCalendar(this.appWorkingDate)
this.fetchCycleData()
},
methods: {
saveField(fieldId, value){
this.openDay[fieldId] = value
},
openDayData(dateCode){
if(String(dateCode).split('.').length != 3){
console.log('Invalid Date Code')
return
}
this.dateCode = dateCode || this.dateCode
let currentDay = this.cycleData[this.dateCode] || {}
//Set up each entry empty or with current value
this.fields.forEach(field => {
currentDay[field.id] = currentDay[field.id] || ''
})
this.openDay = currentDay
},
saveDayData(){
// remove empty keys
let cleanDayData = {}
Object.keys(this.openDay).forEach(key => {
if(this.openDay[key] != ''){
cleanDayData[key] = this.openDay[key]
}
})
this.cycleData[this.dateCode] = cleanDayData
// Update calendar
this.setupCalendar(this.appWorkingDate)
this.saveCycleData()
},
fetchCycleData(){
axios.post('/api/cycle-tracking/get')
.then(({ data }) => {
if(data.hasOwnProperty("text")){
let appData = null
try {
appData = JSON.parse(data.text)
} catch(e) {
console.log('Didnt parse json')
}
console.log(appData)
this.cycleData = appData?.cycleData || {}
this.fields = appData?.fields || []
this.$nextTick(() => {
this.setupFields()
this.openDayData(this.dateCode)
})
}
})
.catch(error => { this.$bus.$emit('notification', error) })
},
saveCycleData(){
const appData = JSON.stringify({
fields: this.fields,
cycleData: this.cycleData,
})
axios.post('/api/cycle-tracking/save', { cycleData:appData })
.then(response => {
{ this.$bus.$emit('notification', 'Data Saved') }
})
.catch(error => { this.$bus.$emit('notification', error) })
},
deleteData(){
axios.post('/api/cycle-tracking/save', { cycleData:'' })
.then(response => {
{ this.$bus.$emit('notification', 'Data Deleted') }
})
},
setupFields(){
// push the first 3 default fields to users set
if(this.fields.length == 0){
for (let i = 0; i < 3; i++) {
this.fields.push(this.defaultFields[i])
}
}
},
setupCalendar(date){
// ------------
// setup calendar display
var y = date.getFullYear()
var m = date.getMonth()
var firstDay = new Date(y, m, 1);
var lastDay = new Date(y, m + 1, 0);
function getDaysInMonth(year, month) {
return new Date(year, month, 0).getDate();
}
const currentYear = date.getFullYear();
const currentMonth = date.getMonth() + 1;
this.calendar.monthName = date.toLocaleString("en-US", { month: "long" });
this.calendar.year = currentYear
const daysInCurrentMonth = getDaysInMonth(currentYear, currentMonth);
const monthStartDay = firstDay.getDay()
let days = Array(monthStartDay).fill("."); // Pad days to start on correct weekday
for (let i = 0; i < daysInCurrentMonth; i++) {
days.push(i+1)
}
this.calendar.days = days
// set today
this.calendar.today = date.getDate()
this.calendar.month = date.getMonth()+1
/*
October 2022
S M T W T F S
1 2 3 4 5 6
7 8 9
*/
// -------
}
}
}
</script>
+4 -4
View File
@@ -562,10 +562,10 @@ export default {
},
beforeCreate(){
//Force HTTPS on prod, always. Dev doesn't have certs
const isDev = process.env['NODE_ENV'] == 'development'
if (!isDev && location.protocol != 'https:'){
window.location.replace('https://www.solidscribe.com')
}
// const isDev = process.env['NODE_ENV'] == 'development'
// if (!isDev && location.protocol != 'https:'){
// window.location.replace('https://www.solidscribe.com')
// }
},
beforeMount(){
+23
View File
@@ -0,0 +1,23 @@
const fs = require("fs");
module.exports = {
pwa: {
name: "SolidScribe",
iconPaths: {
favicon32: null,
favicon16: null,
appleTouchIcon: null,
maskIcon: null,
msTileImage: null,
},
},
// devServer: {
// disableHostCheck: true,
// proxy: "http://localhost:8081",
// public: "blarvin.local",
// https: {
// key: fs.readFileSync("./certs/192.168.1.164+4-key.pem"),
// cert: fs.readFileSync("./certs/192.168.1.164+4.pem"),
// },
// },
};
@@ -0,0 +1,97 @@
#
# Working dev server config
#
server {
listen 80;
listen [::]:80;
server_name 192.168.1.164;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
ssl_certificate /home/mab/ss/client/certs/nginx-selfsigned.crt;
ssl_certificate_key /home/mab/ss/client/certs/nginx-selfsigned.key;
ssl_dhparam /home/mab/ss/client/certs/dhparam.pem;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_protocols TLSV1.1 TLSV1.2 TLSV1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
access_log /var/log/nginx/httpslocalhost.access.log;
error_log /var/log/nginx/httpslocalhost.error.log;
client_max_body_size 20M;
location / {
proxy_pass https://127.0.0.1:8081;
proxy_set_header Host localhost;
proxy_set_header X-Forwarded-Host localhost;
proxy_set_header X-Forwarded-Server localhost;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_redirect off;
proxy_connect_timeout 90s;
proxy_read_timeout 90s;
proxy_send_timeout 90s;
proxy_ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
}
location /sockjs-node {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_pass https://127.0.0.1:8081;
proxy_redirect off;
proxy_ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
}
location /api {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://127.0.0.1:3000;
proxy_redirect off;
proxy_ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
}
location /socket {
proxy_pass http://127.0.0.1:3001;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host;
}
}
# Prod settings to serve static index
# location / {
# autoindex on;
# #try_files $uri $uri/ /index.html;
# }
# location / {
# #autoindex on
#
# proxy_pass http://127.0.0.1:8444;
# proxy_http_version 1.1;
# proxy_set_header Upgrade $http_upgrade;
# proxy_set_header Connection 'upgrade';
# proxy_set_header Host $host;
# proxy_cache_bypass $http_upgrade;
# }
+66
View File
@@ -0,0 +1,66 @@
let db = require('@config/database')
let Note = require('@models/Note')
let CycleTracking = module.exports = {}
CycleTracking.get = (userId, masterKey) => {
return new Promise((resolve, reject) => {
db.promise()
.query(`
SELECT note.id FROM note WHERE quick_note = 2 AND user_id = ? LIMIT 1`, [userId])
.then((rows, fields) => {
//Quick Note is set, return note object
if(rows[0][0] != undefined){
let noteId = rows[0][0].id
const note = Note.get(userId, noteId, masterKey)
.then(noteData => {
return resolve(noteData)
})
} else {
//Or create a new note
let finalId = null
return Note.create(userId, 'Cycle Tracking', '', masterKey)
.then(insertedId => {
finalId = insertedId
db.promise().query('UPDATE note SET quick_note = 2 WHERE id = ? AND user_id = ?',[insertedId, userId])
.then((rows, fields) => {
const note = Note.get(userId, finalId, masterKey)
.then(noteData => {
return resolve(noteData)
})
})
})
}
})
.catch(console.log)
})
}
CycleTracking.save = (userId, cycleData, masterKey) => {
return new Promise((resolve, reject) => {
let finalId = null
CycleTracking.get(userId, masterKey)
.then(noteObject => {
return Note.update(userId, noteObject.id, cycleData, noteObject.title, noteObject.color, noteObject.pinned, noteObject.archived, null, masterKey)
})
.then( saveResults => {
return resolve(saveResults)
})
})
}
+41
View File
@@ -0,0 +1,41 @@
//
// /api/cycle-tracking
//
var express = require('express')
var router = express.Router()
let CycleTracking = require('@models/CycleTracking');
let userId = null
let masterKey = null
// middleware that is specific to this router
router.use(function setUserId (req, res, next) {
//Session key is required to continue
if(!req.headers.sessionId){
next('Unauthorized')
}
if(req.headers.userId){
userId = req.headers.userId
masterKey = req.headers.masterKey
next()
}
})
//Get quick note text
router.post('/get', function (req, res) {
CycleTracking.get(userId, masterKey)
.then( data => res.send(data) )
})
//Push text to quick note
router.post('/save', function (req, res) {
CycleTracking.save(userId, req.body.cycleData, masterKey)
.then( data => res.send(data) )
})
module.exports = router
+39
View File
@@ -0,0 +1,39 @@
with import <nixpkgs> { };
let
pythonPackages = python311Packages;
in pkgs.mkShell rec {
name = "Solid Scribe Env";
buildInputs = [
# node for server
nodejs
nodePackages.npm
pm2
];
# Run this command, only after creating the virtual environment
postVenvCreation = ''
unset SOURCE_DATE_EPOCH
'';
postShellHook = ''
if [[ ! -f lockfile.running ]] ; then
echo "No Lock File, starting servers"
touch lockfile.running
# start service
# npm run start or whatever
fi
# kill everything when main screen is closed
function end {
echo "Exiting, Removing Lockfile"
rm -f lockfile.running
}
trap end EXIT
'';
}
-2
View File
@@ -1,5 +1,3 @@
#!/bin/bash
cd /home/mab/ss
echo '::--:: Starting dev server. cd client; npm run serve -> 192.168.1.164:8081'
+4
View File
@@ -0,0 +1,4 @@
*
*/
!.gitignore
!assets
Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 23 KiB

-1
View File
@@ -19,6 +19,5 @@
],
"name": "Solid Scribe",
"short_name": "Solid Scribe",
"start_url": "/#/notes",
"author":"Max"
}