* Added an auth screen that isn't integrated at all or working
* Force logout of user with authorization error * Wrong site blocker doesn't trigger on the solid scribe domain * Added log out button to main side bar making it easier to find * Improved icon set for notes * Colored notes display better on mobile, fixed text color based on color brightness * Moved terms of use link to the bottom of a few pages * Updated feature sections on home page, make them clearer and easier to process * Tweaked color themes * Deleted links no longer show up in search * Updated search to use multiple key words * Updated tests to do a multi word search * Tweaked a bunch of styles to look better on chrome and browsers
This commit is contained in:
1 parent
b34a62e114
commit
b0c487404c
17 files changed
+399
-193
No files matched your search
+59
-7
@@ -13,6 +13,37 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="auth-block" v-if="requireAuth">
|
||||
<div class="ui raised inverted segment">
|
||||
<div class="ui centered header">
|
||||
Authentication Required
|
||||
</div>
|
||||
<div class="ui small inverted centered header" v-if="$store.getters.getUsername">
|
||||
<i class="green user outline icon"></i>
|
||||
{{ $store.getters.getUsername }}
|
||||
</div>
|
||||
|
||||
<div class="ui large form">
|
||||
<div class="field">
|
||||
<div class="ui small inverted header">Password</div>
|
||||
<div class="ui input">
|
||||
<input type="password" v-model="password" placeholder="Password">
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="ui small inverted header">One Time Password</div>
|
||||
<div class="ui input">
|
||||
<input type="password" v-model="otp" placeholder="One Time Password">
|
||||
</div>
|
||||
</div>
|
||||
<div class="ui fluid inverted black button">
|
||||
<i class="unlock icon"></i>
|
||||
Submit</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<global-site-menu v-if="!showFakeSite" />
|
||||
|
||||
@@ -31,14 +62,18 @@ import axios from 'axios'
|
||||
export default {
|
||||
components: {
|
||||
'global-site-menu': require('@/components/GlobalSiteMenu.vue').default,
|
||||
'global-notification':require('@/components/GlobalNotificationComponent.vue').default
|
||||
'global-notification':require('@/components/GlobalNotificationComponent.vue').default,
|
||||
},
|
||||
data: function(){
|
||||
return {
|
||||
showFakeSite:false, //Incorrect domain detection
|
||||
redirectSeconds: 15,
|
||||
fetchingInProgress: false, //Prevent start getting token while fetch is in progress
|
||||
blockUntilNextRequest: false //If token was just renewed, don't fetch more until next request
|
||||
blockUntilNextRequest: false, //If token was just renewed, don't fetch more until next request
|
||||
|
||||
requireAuth: false,
|
||||
password: '',
|
||||
otp: '',
|
||||
}
|
||||
},
|
||||
|
||||
@@ -81,6 +116,16 @@ export default {
|
||||
return response
|
||||
},
|
||||
(error) => {
|
||||
|
||||
//Catch all authorization errors, log user out if we encounter one
|
||||
if(error.response && error.response.status == 401){
|
||||
|
||||
this.$router.push('/')
|
||||
this.$store.commit('destroyLoginToken')
|
||||
this.$bus.$emit('notification', 'Error: You have been logged out.')
|
||||
|
||||
}
|
||||
|
||||
return Promise.reject(error)
|
||||
}
|
||||
)
|
||||
@@ -127,7 +172,7 @@ export default {
|
||||
mounted: function(){
|
||||
|
||||
const isDev = process.env['NODE_ENV'] == 'development'
|
||||
if(window.location.hostname.toLowerCase() != "www.solidscribe.com" && !isDev){
|
||||
if(window.location.hostname.toLowerCase().replace('www.','') != "solidscribe.com" && !isDev){
|
||||
this.showFakeSite = true
|
||||
setInterval(() => {
|
||||
this.redirectSeconds--
|
||||
@@ -162,16 +207,23 @@ export default {
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
destroyLoginToken() {
|
||||
this.$store.commit('destroyLoginToken')
|
||||
},
|
||||
loginGateway() {
|
||||
if(!this.loggedIn){
|
||||
console.log('This user is not logged in')
|
||||
this.$router.push({'path':'/login'})
|
||||
return
|
||||
}
|
||||
}
|
||||
},
|
||||
logout() {
|
||||
|
||||
this.$router.push('/')
|
||||
axios.post('/api/user/logout')
|
||||
|
||||
setTimeout(() => {
|
||||
this.$store.commit('destroyLoginToken')
|
||||
this.$bus.$emit('notification', 'Logged Out')
|
||||
}, 200)
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -39,6 +39,10 @@
|
||||
|
||||
html {
|
||||
/*scrollbar-width: none;*/
|
||||
width: 100%;
|
||||
height:100%;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
a:hover {
|
||||
text-decoration: underline;
|
||||
@@ -47,6 +51,15 @@ div.ui.basic.segment.no-fluf-segment {
|
||||
margin-top: 0px;
|
||||
}
|
||||
|
||||
.page-container {
|
||||
/*width: 100%;*/
|
||||
display: block;
|
||||
margin: 0;
|
||||
padding: 0.5rem;
|
||||
box-sizing: border-box;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* Night mode modifiers */
|
||||
|
||||
/*Make images sepia in night mode */
|
||||
@@ -268,7 +281,7 @@ i.green.icon.icon.icon.icon {
|
||||
/*height: calc(100% - 69px);*/
|
||||
|
||||
min-height: 500px;
|
||||
background-color: rgba(255,200,0,0.0);
|
||||
background-color: var(--small_element_bg_color);
|
||||
/*margin-bottom: 15px;*/
|
||||
|
||||
box-sizing: border-box;
|
||||
@@ -282,6 +295,10 @@ i.green.icon.icon.icon.icon {
|
||||
scrollbar-width: none;
|
||||
scrollbar-color: transparent transparent;
|
||||
caret-color: var(--main-accent);
|
||||
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
max-width: 1100px;
|
||||
}
|
||||
.squire-box::selection,
|
||||
.squire-box::-moz-selection {
|
||||
@@ -469,7 +486,7 @@ i.green.icon.icon.icon.icon {
|
||||
@media only screen and (max-width: 740px) {
|
||||
|
||||
.squire-box {
|
||||
min-height: calc(100vh - 120px);
|
||||
min-height: calc(100vh - 122px);
|
||||
}
|
||||
|
||||
.ui.button.shrinking {
|
||||
@@ -549,6 +566,27 @@ i.green.icon.icon.icon.icon {
|
||||
animation: fade-in-fwd 0.8s both;
|
||||
}
|
||||
|
||||
/* div that comes up, blocking interaction annd requiring authentication */
|
||||
.auth-block {
|
||||
background-color: rgba(0,0,0,0.9);
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
height: 100vh;
|
||||
width: 100%;
|
||||
z-index: 200;
|
||||
}
|
||||
.auth-block > div {
|
||||
position: absolute;
|
||||
top: 40%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -40%);
|
||||
width: 300px;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ----------------------------------------
|
||||
* animation fade-in-fwd
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
<div class="sixteen wide column">
|
||||
<br>
|
||||
<p>Note Color</p>
|
||||
<div v-for="color in getReducedColors()"
|
||||
<div v-for="color in colors"
|
||||
class="color-button"
|
||||
:style="{ backgroundColor:color }"
|
||||
v-on:click="chosenColor(color)"
|
||||
@@ -66,7 +66,7 @@
|
||||
blankStyle:{ 'noteText':null,'noteBackground':null, 'noteIcon':null, 'iconColor':null },
|
||||
colors: [null,
|
||||
'rgb(67,67,67)','rgb(102,102,102)','rgb(153,153,153)','rgb(183,183,183)','rgb(204,204,204)','rgb(217,217,217)','rgb(239,239,239)','rgb(243,243,243)','rgb(255,255,255)','rgb(152,0,0)','rgb(255,0,0)','rgb(255,153,0)','rgb(255,255,0)','rgb(0,255,0)','rgb(0,255,255)','rgb(74,134,232)','rgb(0,0,255)','rgb(153,0,255)','rgb(255,0,255)','rgb(230,184,175)','rgb(244,204,204)','rgb(252,229,205)','rgb(255,242,204)','rgb(217,234,211)','rgb(208,224,227)','rgb(201,218,248)','rgb(207,226,243)','rgb(217,210,233)','rgb(234,209,220)','rgb(221,126,107)','rgb(234,153,153)','rgb(249,203,156)','rgb(255,229,153)','rgb(182,215,168)','rgb(162,196,201)','rgb(164,194,244)','rgb(159,197,232)','rgb(180,167,214)','rgb(213,166,189)','rgb(204,65,37)','rgb(224,102,102)','rgb(246,178,107)','rgb(255,217,102)','rgb(147,196,125)','rgb(118,165,175)','rgb(109,158,235)','rgb(111,168,220)','rgb(142,124,195)','rgb(194,123,160)','rgb(166,28,0)','rgb(204,0,0)','rgb(230,145,56)','rgb(241,194,50)','rgb(106,168,79)','rgb(69,129,142)','rgb(60,120,216)','rgb(61,133,198)','rgb(103,78,167)','rgb(166,77,121)','rgb(133,32,12)','rgb(153,0,0)','rgb(180,95,6)','rgb(191,144,0)','rgb(56,118,29)','rgb(19,79,92)','rgb(17,85,204)','rgb(11,83,148)','rgb(53,28,117)','rgb(116,27,71)','rgb(91,15,0)','rgb(102,0,0)','rgb(120,63,4)','rgb(127,96,0)','rgb(39,78,19)','rgb(12,52,61)','rgb(28,69,135)','rgb(7,55,99)','rgb(32,18,77)','rgb(76,17,48)'],
|
||||
icons: ['ambulance','anchor','balance scale','bath','bed','beer','bell','bell slash','bell slash outline','bicycle','binoculars','birthday cake','blind','bomb','book','bookmark','briefcase','building','car','coffee','crosshairs','dollar sign','eye','eye slash','fighter jet','fire','fire extinguisher','flag','flag checkered','flask','gamepad','gavel','gift','glass martini','globe','graduation cap','h square','heart','heart outline','heartbeat','home','hospital','hospital outline','image','image outline','images','images outline','industry','info','info circle','key','leaf','lemon','lemon outline','life ring','life ring outline','lightbulb','lightbulb outline','location arrow','low vision','magnet','male','map','map outline','map marker','map marker alternate','map pin','map signs','medkit','money bill alternate','money bill alternate outline','motorcycle','music','newspaper','newspaper outline','paw','phone','phone square','phone volume','plane','plug','plus','plus square','plus square outline','print','recycle','road','rocket','search','search minus','search plus','ship','shopping bag','shopping basket','shopping cart','shower','street view','subway','suitcase','tag','tags','taxi','thumbtack','ticket alternate','tint','train','tree','trophy','truck','tty','umbrella','university','utensil spoon','utensils','wheelchair','wifi','wrench']
|
||||
icons: ['cat','crow','dog','dove','dragon','feather','feather alternate','fish','frog','hippo','horse','horse head','kiwi bird','otter','paw','spider','video','headphones','motorcycle','truck','monster truck','campground','cloud sun','drumstick bite','football ball','fruit-apple','hiking','mountain','tractor','tree','wind','wine bottle','coffee','flask','glass cheers','glass martini','beer','toilet paper','gift','globe','hand holding heart','comment','graduation cap','hat cowboy','hat wizard','mitten','user tie','laptop code','microchip','shield alternate','mouse','plug','power off','satellite','hammer','wrench','bell','eye','marker','paperclip','atom','award','theater masks','music','grin alternate','grin tongue squint outline','laugh wink','fire','fire alternate','poop','sun','money bill alternate','piggy bank','heart outline','heartbeat','running','walking','bacon','bone','bread slice','candy cane','carrot','cheese','cloud meatball','cookie','egg','hamburger','hotdog','ice cream','lemon','lemon outline','pepper hot','pizza slice','seedling','stroopwafel','leaf','book dead','broom','cloud moon','ghost','mask','skull crossbones','certificate','check','check circle','joint','cannabis','bong','gem','futbol','brain','dna','hand spock','hand spock outline','meteor','moon','moon outline','robot','rocket','satellite dish','space shuttle','user astronaut','fingerprint','thumbs up','thumbs down']
|
||||
}
|
||||
},
|
||||
watch:{
|
||||
@@ -83,17 +83,11 @@
|
||||
let reduced = []
|
||||
|
||||
this.colors.forEach((color,i) => {
|
||||
|
||||
|
||||
let mod = (i % 10)+1 //1 - 10
|
||||
let lines = [3, 5, 8, 9, 10]
|
||||
// if(lines.includes(mod)){
|
||||
if(i < 20 || i > 69){
|
||||
reduced.push(color)
|
||||
// }
|
||||
}
|
||||
})
|
||||
|
||||
reduced.push("#000")
|
||||
|
||||
return reduced
|
||||
},
|
||||
clearStyles(){
|
||||
@@ -114,12 +108,17 @@
|
||||
|
||||
//Automatically select note text color
|
||||
|
||||
//If you are using hex colors, use this
|
||||
// Convert hex color to RGB - http://gist.github.com/983661
|
||||
let color = +("0x" + inColor.slice(1).replace(inColor.length < 5 && /./g, '$&$&'));
|
||||
// let color = +("0x" + inColor.slice(1).replace(inColor.length < 5 && /./g, '$&$&'));
|
||||
// let r = color >> 16;
|
||||
// let g = color >> 8 & 255;
|
||||
// let b = color & 255;
|
||||
|
||||
let r = color >> 16;
|
||||
let g = color >> 8 & 255;
|
||||
let b = color & 255;
|
||||
const set = inColor.match(/\d+/g)
|
||||
const r = parseInt(set[0])
|
||||
const g = parseInt(set[1])
|
||||
const b = parseInt(set[2])
|
||||
|
||||
//Convert RGB to HSP
|
||||
const hsp = Math.sqrt( 0.299 * (r * r) + 0.587 * (g * g) + 0.114 * (b * b) );
|
||||
|
||||
@@ -83,6 +83,7 @@
|
||||
/*padding: 5px 1rem 5px;*/
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
width: 100vw;
|
||||
}
|
||||
.place-holder {
|
||||
width: 100%;
|
||||
@@ -277,20 +278,18 @@
|
||||
</router-link>
|
||||
</div>
|
||||
|
||||
<div class="menu-section">
|
||||
<router-link class="menu-item menu-button" exact-active-class="active" to="/terms">
|
||||
<i class="info circle icon"></i>Terms
|
||||
<div class="menu-section" v-if="loggedIn">
|
||||
<router-link class="menu-item menu-button" exact-active-class="active" to="/settings">
|
||||
<i class="cog icon"></i>Settings
|
||||
</router-link>
|
||||
</div>
|
||||
|
||||
<div class="menu-section" v-if="loggedIn">
|
||||
<router-link class="menu-item menu-button" exact-active-class="active" to="/settings">
|
||||
<i v-if="userIcon" class="cog icon"></i>{{ usernameDisplay }}
|
||||
</router-link>
|
||||
<div class="menu-item menu-button" v-on:click="logout()">
|
||||
<i class="log out icon"></i>Log Out
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div v-on:click="reloadPage" class="version-display" v-if="version != 0" >
|
||||
<i :class="`${getVersionIcon()} icon`"></i> {{ version }}
|
||||
</div>
|
||||
@@ -348,24 +347,18 @@
|
||||
//Map logged in from state
|
||||
return this.$store.getters.getLoggedIn
|
||||
},
|
||||
usernameDisplay() {
|
||||
|
||||
//Remove Emails from username, limit length to 16 chars
|
||||
let name = this.$store.getters.getUsername
|
||||
let splitName = name.split('@')
|
||||
if(splitName.length > 1){
|
||||
name = splitName.shift()
|
||||
this.userIcon = false
|
||||
}
|
||||
|
||||
if(name.length > 16){
|
||||
this.userIcon = false
|
||||
}
|
||||
|
||||
return this.ucWords(name.substring(0, 16))
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
logout() {
|
||||
|
||||
this.$router.push('/')
|
||||
axios.post('/api/user/logout')
|
||||
|
||||
setTimeout(() => {
|
||||
this.$store.commit('destroyLoginToken')
|
||||
this.$bus.$emit('notification', 'Logged Out')
|
||||
}, 200)
|
||||
},
|
||||
newQuickNote(){
|
||||
|
||||
axios.post('/api/quick-note/get')
|
||||
|
||||
@@ -73,8 +73,10 @@
|
||||
<style type="text/css" scoped>
|
||||
.darken-accent {
|
||||
filter: brightness(62%);
|
||||
-webkit-filter: brightness(62%);
|
||||
}
|
||||
.brighten-accent {
|
||||
filter: saturate(145%);
|
||||
-webkit-filter: saturate(145%);
|
||||
}
|
||||
</style>
|
||||
@@ -133,10 +133,11 @@
|
||||
|
||||
<div class="bottom-edit-menu"></div>
|
||||
|
||||
<div class="input-container-wrapper" :class="{ 'side-menu-open':sideMenuOpen, 'size-down':(sizeDown == true),}">
|
||||
<div class="input-container-wrapper"
|
||||
:class="{ 'side-menu-open':sideMenuOpen, 'size-down':(sizeDown == true),}">
|
||||
|
||||
<!-- Squire box grows -->
|
||||
<div id="text-box-container" class="note-wrapper" :style="{ 'background-color':styleObject['noteBackground'], 'color':styleObject['noteText']}">
|
||||
<div id="text-box-container" class="note-wrapper">
|
||||
|
||||
<!-- Loading indicator -->
|
||||
<transition name="fade">
|
||||
@@ -154,12 +155,17 @@
|
||||
v-on:keydown="titleResize"
|
||||
@keydown.enter.exact.prevent="editor.focus(); editor.moveCursorToEnd()"
|
||||
rows="1"
|
||||
:style="{ 'background-color':styleObject['noteBackground'], 'color':styleObject['noteText']}"
|
||||
:style="{ 'background-color':styleObject['noteBackground'], 'color':styleObject['noteText'] }"
|
||||
v-on:blur="save" type="text" v-model="noteTitle" placeholder="Title" class="stealth-input">
|
||||
</textarea>
|
||||
|
||||
<!-- Squire Box -->
|
||||
<div id="squire-id" class="squire-box" ref="squirebox" placeholder="Type Note Here"></div>
|
||||
<div
|
||||
id="squire-id"
|
||||
class="squire-box"
|
||||
ref="squirebox"
|
||||
:style="{ 'background-color':styleObject['noteBackground'], 'color':styleObject['noteText'] }"
|
||||
placeholder="Type Note Here"></div>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -1248,14 +1254,20 @@
|
||||
.stealth-input {
|
||||
width: 100%;
|
||||
padding: 10px 15px 5px;
|
||||
background-color: rgba(255,255,255,0.1);
|
||||
background-color: var(--small_element_bg_color );
|
||||
border: none;
|
||||
font-size: 1.7em;
|
||||
color: var(--text_color);
|
||||
caret-color: var(--main-accent);
|
||||
resize: none;
|
||||
overflow: hidden;
|
||||
margin: 0;
|
||||
/*margin: 0;*/
|
||||
outline: none;
|
||||
display: block;
|
||||
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
max-width: 1100px;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,12 @@
|
||||
class="small-text"
|
||||
v-html="note.subtext"></span>
|
||||
|
||||
|
||||
<!-- Not indexed warning -->
|
||||
<!-- <span v-if="note.indexed != 1">
|
||||
<span class="green label">Not Indexed</span>
|
||||
</span> -->
|
||||
|
||||
|
||||
<div class="ui fluid basic button" v-if="note.encrypted == 1">
|
||||
<i class="green lock icon"></i>
|
||||
@@ -410,6 +416,7 @@
|
||||
background-color: var(--small_element_bg_color);
|
||||
/*The subtle shadow*/
|
||||
/*box-shadow: 0px 1px 2px 1px rgba(210, 211, 211, 0.46);*/
|
||||
box-shadow: 2px 2px 6px 0 rgba(0,0,0,.15);
|
||||
transition: box-shadow ease 0.5s, transform linear 0.1s;
|
||||
margin: 5px;
|
||||
/*padding: 0.7em 1em;*/
|
||||
@@ -562,7 +569,7 @@
|
||||
@media only screen and (max-width: 700px) {
|
||||
.note-title-display-card {
|
||||
width: calc(100% + 10px);
|
||||
margin: 0px -5px 10px -5px;
|
||||
/*margin: 0px -5px 10px -5px;*/
|
||||
}
|
||||
}
|
||||
@media only screen and (min-width: 700px) and (max-width: 900px) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<style type="text/css" scoped>
|
||||
.colors {
|
||||
position: absolute;
|
||||
position: fixed;
|
||||
z-index: 1023;
|
||||
top: 5px;
|
||||
/*height: 100px;*/
|
||||
|
||||
@@ -8,6 +8,12 @@
|
||||
|
||||
<p><u>Encrypted Data</u><br></p><blockquote><p>Note text, note title and the note search index is fully encrypted. <br></p><p><br></p><p>Encryption is the transformation of data into a form unreadable by anyone without the password. Its purpose is to ensure privacy by keeping the information hidden from anyone for whom it is not intended, even those who can see the encrypted data. If every note in the database was leaked, nothing would be readable. If the government asked for your notes, it would all be gibberish. <br></p></blockquote><p><br></p><p><u>Some Data is not encrypted</u><br></p><blockquote><p>To keep up ease of use, your Username, Files, Tags, Attachments and attachment search text is not encrypted.<br></p></blockquote><p><br></p><p><u>Searching</u><br></p><blockquote><p>Note text searching is limited to key words.<br></p><p>To allow for higher security, the complexity of the search index has been reduced. To make sure that every word of every note is fully encrypted, the search index is encrypted as well. <br></p></blockquote><p><br></p><p><u>Files</u><br></p><blockquote><p>The files section will show files that have been uploaded to notes or web pages that have been scraped from notes.<br></p><p><br></p><p>The text next to each file can be modified and found later with the search bar. <br></p><p>Files are limited to 5MB in size. <br></p><p><br></p><p>Files can be uploaded to notes. If its an image, the picture will be put into the note.<br></p><p>Images added to notes will have text scanned, so it can be searched (This isn't super accurate so don't rely to heavily on it.) The text can be updated at any time and searched later.<br></p></blockquote><p><br></p><p><u>Scratch Pad</u><br></p><blockquote><p>The Scratch Pad was designed to allow rapid input to a single note. Rather than junking up all your notes with random links, numbers or haikus, you can put them all in one place. <br></p></blockquote><p><br></p><p><u>Flux Theme</u><br></p><blockquote><p>Flux theme limits the amount of blue emitted by your screen. Most things turn sepia and a filter is applied to images to make them more sepia. Less blue light at night is supposed to be helpful for falling asleep.<br></p><p>Here is some good research on the topic: <a href="https://justgetflux.com/research.html">https://justgetflux.com/research.html</a><br></p></blockquote><p><br></p><p><u>Text Editor Keyboard Shortcuts</u><br></p><blockquote><ul><li><b>Number List</b> - CTRL + SHIFT + 9<br></li><li><b>Todo List</b> - CTRL + SHIFT + 8<br></li><li><b>Underline</b> - CTRL + u<br></li><li><b>Bold</b> - CTRL + b<br></li><li><b>Quote</b> - CRTL + i<br></li><li><b>Undo</b> - CTRL + z<br></li><li><b>Redo</b> - CTRL + y<br></li><li><b>Indent</b> - TAB<br></li><li><b>Un-Indent</b> - SHIFT + TAB<br></li><li><b>Manual Save</b> - CTRL + S<br></li><li><b>Close Note</b> - ESC<br></li></ul></blockquote><p><br></p><p><u>Shared Notes</u><br></p><blockquote><p>Shared notes still respect privacy but use a different security scheme. Instead of encrypting the note with your password, a shared password is created. This note then uses <a href="https://en.wikipedia.org/wiki/Public-key_cryptography">public-key cryptography</a> to share the note with other users, while still making it unreadable to anyone else. <br></p><ul><li>You can revoke any users access to a shared note at any time.<br></li><li>Notes you share can not be shared by other people.<br></li><li>If you turn off sharing, all users lose access and the note is reverted to the default security scheme.<br></li></ul><p><br></p><p>It is possible to generate a public URL for shared notes. This exposes the Encryption Key for the note. Anyone with the key to the note can read that note. The encryption key to a shared note can easily be changed by turning off sharing, then turning it back on. <br></p><p><u><br></u></p></blockquote><p><u>Links in notes</u><br></p><blockquote><p>Links put into notes are automatically scraped. This means the data from the link will be scanned to get an image and some text from the website to help make that link more accessible in the future. <br></p><p>You can edit the text of scarped links and any time and search for it later. <br></p></blockquote><p><br></p><p><u>Deleting Notes</u><br></p><blockquote><p>Deleting a note from the trash erases all note text and the note entry. It can not be recovered.<br></p><p>None of the files related to the note are deleted. They can be manually removed at any time.<br></p></blockquote><p><br></p><p><u>Daily Backups</u><br></p><blockquote><p>All notes are backed up, every night, at midnight. If there is data loss, it can be restored from a backup. If you experience some sort of cataclysmic data loss please contact the system administrator for a copy of your data or a restoration procedure. <br></p><p>All data in the backups remains encrypted and unreadable.<br></p></blockquote><p><br></p><p><u>Two Factor Authentication (2FA)</u><br></p><blockquote>Line truncated
|
||||
|
||||
<div class="ui grid">
|
||||
<div class="center aligned sixteen wide column">
|
||||
<router-link to="/terms"></i>Solid Scribe Terms of Use</router-link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
+127
-81
@@ -167,8 +167,10 @@
|
||||
<!-- Overview -->
|
||||
<div class="middle aligned centered row">
|
||||
<div class="six wide column">
|
||||
<h2>Solid Scribe focuses on powerful text editing and user privacy</h2>
|
||||
<h3>Tools to organize and collaborate on thousands of notes while maintaining security and respecting your privacy.</h3>
|
||||
<h2>Powerful text editing and privacy</h2>
|
||||
<h3>Easily edit, share and organize thousands of notes.</h3>
|
||||
<h3>Feel safe knowing no one can read your notes but you.</h3>
|
||||
<!-- <h3>Tools to organize and collaborate on thousands of notes while maintaining security and respecting your privacy.</h3> -->
|
||||
</div>
|
||||
<div class="four wide column">
|
||||
<img loading="lazy" width="100%" src="/api/static/assets/marketing/idea.svg" alt="Explosion of New Ideas">
|
||||
@@ -176,52 +178,21 @@
|
||||
</div>
|
||||
|
||||
<!-- features list -->
|
||||
<div class="middle aligned centered row">
|
||||
<div class="sixteen wide column">
|
||||
<h1 class="ui center aligned header"><i class="sliders horizontal icon"></i>Features</h1>
|
||||
</div>
|
||||
<div class="top aligned centered row">
|
||||
|
||||
<!-- note features -->
|
||||
<div class="six wide column">
|
||||
<h2 class="ui dividing header">
|
||||
<div class="content">
|
||||
<i class="icons">
|
||||
<i class="grey lock icon"></i>
|
||||
<i class="bottom left corner yellow key icon"></i>
|
||||
</i>
|
||||
Privacy Focused
|
||||
<div class="sub header">All note text is encrypted. No one can read your notes. None of your data is shared.</div>
|
||||
</div>
|
||||
</h2>
|
||||
|
||||
<h1 class="ui center aligned header"><i class="sliders horizontal icon"></i>App Features</h1>
|
||||
|
||||
<h2 class="ui dividing header">
|
||||
<div class="content">
|
||||
<i class="icons">
|
||||
<i class="grey list icon"></i>
|
||||
<i class="bottom left corner green check icon"></i>
|
||||
<i class="grey sticky note icon"></i>
|
||||
<i class="bottom left corner teal plus icon"></i>
|
||||
</i>
|
||||
To Do Lists
|
||||
<div class="sub header">Create To Do lists that are always synced, work on mobile and can be sorted.</div>
|
||||
</div>
|
||||
</h2>
|
||||
|
||||
<h2 class="ui dividing header">
|
||||
<div class="content">
|
||||
<i class="icons">
|
||||
<i class="grey file icon"></i>
|
||||
<i class="bottom left corner blue pen icon"></i>
|
||||
</i>
|
||||
Document Editing Tools
|
||||
<div class="sub header">Bold, Underline, Title, Add Links, Add Tables, Color Text, Color Background and more.</div>
|
||||
</div>
|
||||
</h2>
|
||||
|
||||
<h2 class="ui dividing header">
|
||||
<div class="content">
|
||||
<i class="icons">
|
||||
<i class="grey images icon"></i>
|
||||
<i class="bottom left corner teal paperclip icon"></i>
|
||||
</i>
|
||||
Add Images
|
||||
<div class="sub header">Upload images to notes, add search text to the images to find them later.</div>
|
||||
Create as many notes as you want
|
||||
<div class="sub header">Create unlimited notes up to 5,000,000 characters long.</div>
|
||||
</div>
|
||||
</h2>
|
||||
|
||||
@@ -232,40 +203,7 @@
|
||||
<i class="bottom left corner purple plus icon"></i>
|
||||
</i>
|
||||
Tag Notes
|
||||
<div class="sub header">Easily add and edit tags on notes then sort notes by tag.</div>
|
||||
</div>
|
||||
</h2>
|
||||
|
||||
<h2 class="ui dividing header">
|
||||
<div class="content">
|
||||
<i class="icons">
|
||||
<i class="grey cloud moon icon"></i>
|
||||
<i class="bottom left corner red eye icon"></i>
|
||||
</i>
|
||||
Night Mode
|
||||
<div class="sub header">Pure black night theme with an even darker flux theme.</div>
|
||||
</div>
|
||||
</h2>
|
||||
|
||||
<h2 class="ui dividing header">
|
||||
<div class="content">
|
||||
<i class="icons">
|
||||
<i class="grey share alternate icon"></i>
|
||||
<i class="bottom left corner share icon"></i>
|
||||
</i>
|
||||
Share Encrypted Notes
|
||||
<div class="sub header">Share encrypted notes with friends without compromising security.</div>
|
||||
</div>
|
||||
</h2>
|
||||
|
||||
<h2 class="ui dividing header">
|
||||
<div class="content">
|
||||
<i class="icons">
|
||||
<i class="grey users icon"></i>
|
||||
<i class="bottom left corner olive exchange icon"></i>
|
||||
</i>
|
||||
Collaborative Note Editing
|
||||
<div class="sub header">Notes instantly update in real time everywhere the note is open.</div>
|
||||
<div class="sub header">Easily add and edit tags on notes then search or sort by tag.</div>
|
||||
</div>
|
||||
</h2>
|
||||
|
||||
@@ -275,8 +213,8 @@
|
||||
<i class="grey search icon"></i>
|
||||
<i class="bottom left corner orange font icon"></i>
|
||||
</i>
|
||||
Keyword Search
|
||||
<div class="sub header">Easily search all notes. Encrypted search index ensures privacy and convenience.</div>
|
||||
Search Note Text
|
||||
<div class="sub header">Easily search all notes, files, links and tags.</div>
|
||||
</div>
|
||||
</h2>
|
||||
|
||||
@@ -291,6 +229,109 @@
|
||||
</div>
|
||||
</h2>
|
||||
|
||||
<h2 class="ui dividing header">
|
||||
<div class="content">
|
||||
<i class="icons">
|
||||
<i class="grey cloud moon icon"></i>
|
||||
<i class="bottom left corner red eye icon"></i>
|
||||
</i>
|
||||
Night Mode
|
||||
<div class="sub header">Pure black night theme with an even darker flux theme.</div>
|
||||
</div>
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<!-- editing features -->
|
||||
<div class="six wide column">
|
||||
<h1 class="ui center aligned header"><i class="sliders horizontal icon"></i>Editing Features</h1>
|
||||
<h2 class="ui dividing header">
|
||||
<div class="content">
|
||||
<i class="icons">
|
||||
<i class="grey list icon"></i>
|
||||
<i class="bottom left corner green check icon"></i>
|
||||
</i>
|
||||
Create To Do Lists
|
||||
<div class="sub header">Create To Do lists that are always synced, work on mobile and can be sorted.</div>
|
||||
</div>
|
||||
</h2>
|
||||
<h2 class="ui dividing header">
|
||||
<div class="content">
|
||||
<i class="icons">
|
||||
<i class="grey file icon"></i>
|
||||
<i class="bottom left corner blue pen icon"></i>
|
||||
</i>
|
||||
Formatting Tools
|
||||
<div class="sub header">Bold, Underline, Title, Add Links, Add Tables, Color Text, Color Background and more.</div>
|
||||
</div>
|
||||
</h2>
|
||||
<h2 class="ui dividing header">
|
||||
<div class="content">
|
||||
<i class="icons">
|
||||
<i class="grey file icon"></i>
|
||||
<i class="bottom left corner orange paint brush icon"></i>
|
||||
</i>
|
||||
Customized Colorful Notes
|
||||
<div class="sub header">Color the background of notes and add colored icons to make them stand out.</div>
|
||||
</div>
|
||||
</h2>
|
||||
<h2 class="ui dividing header">
|
||||
<div class="content">
|
||||
<i class="icons">
|
||||
<i class="grey images icon"></i>
|
||||
<i class="bottom left corner teal paperclip icon"></i>
|
||||
</i>
|
||||
Add Images
|
||||
<div class="sub header">Upload images to notes, add search text to the images to find them later.</div>
|
||||
</div>
|
||||
</h2>
|
||||
<h2 class="ui dividing header">
|
||||
<div class="content">
|
||||
<i class="icons">
|
||||
<i class="grey users icon"></i>
|
||||
<i class="bottom left corner olive exchange icon"></i>
|
||||
</i>
|
||||
Collaborative Note Editing
|
||||
<div class="sub header">Notes instantly update in real time everywhere its open and anywhere its shared.</div>
|
||||
</div>
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="middle aligned centered row">
|
||||
<!-- privacy features -->
|
||||
<div class="six wide column">
|
||||
<h1 class="ui center aligned header"><i class="sliders horizontal icon"></i>Privacy Features</h1>
|
||||
<h2 class="ui dividing header">
|
||||
<div class="content">
|
||||
<i class="icons">
|
||||
<i class="grey lock icon"></i>
|
||||
<i class="bottom left corner yellow key icon"></i>
|
||||
</i>
|
||||
All Note Text is Encrypted
|
||||
<div class="sub header">All note text is encrypted. No one can read your notes. None of your data is shared.</div>
|
||||
</div>
|
||||
</h2>
|
||||
<h2 class="ui dividing header">
|
||||
<div class="content">
|
||||
<i class="icons">
|
||||
<i class="grey search icon"></i>
|
||||
<i class="bottom left corner orange font icon"></i>
|
||||
</i>
|
||||
Note Search is Encrypted
|
||||
<div class="sub header">Easily search the contents of all your notes without compromising security.</div>
|
||||
</div>
|
||||
</h2>
|
||||
<h2 class="ui dividing header">
|
||||
<div class="content">
|
||||
<i class="icons">
|
||||
<i class="grey share alternate icon"></i>
|
||||
<i class="bottom left corner share icon"></i>
|
||||
</i>
|
||||
Encrypted Note Sharing
|
||||
<div class="sub header">Shared notes are still encrypted, only readable by you and the shared users.</div>
|
||||
</div>
|
||||
</h2>
|
||||
<h2 class="ui dividing header">
|
||||
<div class="content">
|
||||
<i class="icons">
|
||||
@@ -301,11 +342,12 @@
|
||||
<div class="sub header">Enable two factor authentication for added peace of mind.</div>
|
||||
</div>
|
||||
</h2>
|
||||
|
||||
</div>
|
||||
<div class="four wide column">
|
||||
|
||||
<div class="six wide column">
|
||||
<img loading="lazy" width="100%" src="/api/static/assets/marketing/onboarding.svg" alt="">
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
@@ -347,7 +389,7 @@
|
||||
<h2>Leave your Ad Blockers turned on</h2>
|
||||
<h3>SolidScribe doesn't load any trackers or ads. It was designed to run on
|
||||
<a href="https://www.mozilla.org/en-US/firefox/new/" target="_blank">Firefox</a>, with
|
||||
<a href="https://addons.mozilla.org/en-US/firefox/addon/ublock-origin/" target="_blank">uBlock Origin</a> and a
|
||||
<a href="https://addons.mozilla.org/en-US/firefox/addon/ublock-origin/" target="_blank">an Ad Blocker</a> turned on. It even works with a
|
||||
<a href="https://pi-hole.net/" target="_blank">Pi-hole</a> on the network.</h3>
|
||||
</div>
|
||||
<div class="four wide column">
|
||||
@@ -423,6 +465,10 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="center aligned sixteen wide column">
|
||||
<router-link to="/terms"></i>Solid Scribe Terms of Use</router-link>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="ui basic segment no-fluf-segment">
|
||||
<div class="page-container">
|
||||
|
||||
<div class="ui grid" ref="content">
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<template>
|
||||
<div class="squire-box">
|
||||
<div class="">
|
||||
<div>
|
||||
|
||||
<h3 class="ui dividing header">
|
||||
<i class="green cog icon"></i>
|
||||
Settings
|
||||
<i class="inline green cog icon"></i>
|
||||
Settings for {{ $store.getters.getUsername }}
|
||||
</h3>
|
||||
|
||||
<h4>New Scratch Pad</h4>
|
||||
@@ -113,19 +113,14 @@
|
||||
</div>
|
||||
|
||||
<!-- log out -->
|
||||
<h4>Log Out</h4>
|
||||
<h4>Revoke Other Active Sessions</h4>
|
||||
<div class="ui segment">
|
||||
<div class="ui stackable grid">
|
||||
<div class="eight wide column">
|
||||
<div class="ui button" v-on:click="logout()">
|
||||
<i class="power off icon"></i>
|
||||
Log Out on this browser
|
||||
</div>
|
||||
</div>
|
||||
<div class="eight wide column">
|
||||
<div class="sixteen wide column">
|
||||
<p>Revoke access on any logged in device, except for the one you are currently using.<br><br></p>
|
||||
<div class="ui button" v-on:click="revokeAllSessions()">
|
||||
<i class="sign out icon"></i>
|
||||
Log Out all other browsers
|
||||
Log Out all other devices
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -154,6 +149,12 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ui grid">
|
||||
<div class="center aligned sixteen wide column">
|
||||
<router-link to="/terms"></i>Solid Scribe Terms of Use</router-link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
@@ -208,14 +209,6 @@
|
||||
})
|
||||
|
||||
},
|
||||
logout() {
|
||||
this.$store.commit('destroyLoginToken')
|
||||
this.$router.push('/')
|
||||
axios.post('/api/user/logout')
|
||||
setTimeout(() => {
|
||||
this.$bus.$emit('notification', 'Logged Out')
|
||||
}, 200)
|
||||
},
|
||||
setAccentColor(color){
|
||||
|
||||
let root = document.documentElement
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
Solid Scribe Terms of Use
|
||||
</h3>
|
||||
|
||||
<p><span class="size" style="font-size: 1.4em">Solid Scribe Terms of Use</span><br></p><p><br></p><p>Welcome to Solid Scribe’s web-based application at solidscribe.com.<br></p><p><br></p><p>Your use of the Site and/or participation in any of the Services offered through the Site, is subject to these Terms of Use.<br></p><p>By registering an account or using the Site you agree to be bound by these Terms of Use.<br></p><p><br></p><p>The Company reserves the right to change these Terms of Use from time to time by publishing them on the Site.<br></p><p>By using the Site, you agree to the most current version of these Terms of Use as posted on the Site.<br></p><p><br></p><p>All content on the Site is provided "as is." Solid Scribe is not liable for any informational errors, incompleteness, delays or any actions taken in reliance on information contained on the Site. The Company cannot and does not guarantee that any content on the Site will be entirely accurate or up-to-date at all times as the information on the Site originates from various sources, which may or may not be within the control of the Company.<br></p><p><br></p><p>The Company is not responsible for any omission, deletion, failure to store, improper delivery or untimely delivery of any information or material. The Company is not responsible for any reliance upon or damage arising from the use of the Site, including technical damage resulting from downloading or accessing any information or material provided.<br></p><p><br></p><p>You understand and agree that the Company is not responsible for any content posted by you or third parties. You further understand that the Company does not monitor the content posted by other users.<br></p><p><br></p><p>The Company reserves the right to remove content that the Company deems inappropriate for any reason what so ever without notice. The Company also reserves the right, in the Company’s sole discretion, to remove a user's privilege to post content on the Site.<br></p><p><br></p><p>The Company does not in any manner endorse the content of its users and cannot and does not vouch for its reliability or otherwise accept liability for it.<br></p><p><br></p><p>Minors (persons under 18 years of age), persons or organizations that cannot enter into binding contracts under applicable law, and those who may be prevented by contractual obligations from entering into binding contracts with Solid Scribe are not allowed to use this Site.<br></p><p><br></p><p>The Company has the right, but not the obligation, to take any of the following actions in the Company’s sole discretion at any time and for any reason without providing you any prior notice:<br></p><p><br></p><p>1. Restrict, suspend, modify or terminate access to the Site or all or any part of the Company’s Services;<br></p><p>2. Change, suspend or discontinue all or any part of the Company’s Services;<br></p><p>3. Refuse, move, modify or remove any material submitted to the Site by any person, for any reason;<br></p><p>4. Refuse, move, modify or remove any content available on the Site;<br></p><p>5. Deactivate or delete your account and all related information and files in your account;<br></p><p>6. Establish, discontinue or change general practices and limits concerning use of the Site and the Company’s Services.<br></p><p><br></p><p>You agree that the Company is not liable to you or any third party for taking any of these actions. Any registration or other eligibility requirements are in the sole discretion of the Company and may be modified for any reason at any time.<br></p><p><br></p><p>YOUR INFORMATION AND CONTENT<br></p><p><br></p><p>Any information you provide to Solid Scribe or other users during your registration or use of the Site (in any public message area, through any mail feature, or otherwise generated out of your use of the Site or the Services), is subject to the following:<br></p><p><br></p><p>(a) You are solely responsible for the content of your information, postings or Notes. The Company reserves the right to take any action with respect to such information that it deems necessary or appropriate in its sole discretion for any reason, including if the Company believes information is inappropriate for the Site or the Services, may create liability for the Company.<br></p><p><br></p><p>(b) You agree that your information will not, to the best of your knowledge: (i) violate any law (including without limitation those governing export control, consumer protection, unfair competition, anti-discrimination or false advertising); or (ii) be libelous, defamatory, obscene, abusive, violate a third party's right to privacy, otherwise violate any applicable local, state, national or international law, amount to spamming or be otherwise inappropriate. You may not post content that degrades others on the basis of gender, race, class, ethnicity, national origin, religion, sexual preference, disability or other classification. Epithets and otherLine truncated
|
||||
<p>Welcome to Solid Scribe’s web-based application at solidscribe.com.<br></p><p><br></p><p>Your use of the Site and/or participation in any of the Services offered through the Site, is subject to these Terms of Use.<br></p><p>By registering an account or using the Site you agree to be bound by these Terms of Use.<br></p><p><br></p><p>The Company reserves the right to change these Terms of Use from time to time by publishing them on the Site.<br></p><p>By using the Site, you agree to the most current version of these Terms of Use as posted on the Site.<br></p><p><br></p><p>All content on the Site is provided "as is." Solid Scribe is not liable for any informational errors, incompleteness, delays or any actions taken in reliance on information contained on the Site. The Company cannot and does not guarantee that any content on the Site will be entirely accurate or up-to-date at all times as the information on the Site originates from various sources, which may or may not be within the control of the Company.<br></p><p><br></p><p>The Company is not responsible for any omission, deletion, failure to store, improper delivery or untimely delivery of any information or material. The Company is not responsible for any reliance upon or damage arising from the use of the Site, including technical damage resulting from downloading or accessing any information or material provided.<br></p><p><br></p><p>You understand and agree that the Company is not responsible for any content posted by you or third parties. You further understand that the Company does not monitor the content posted by other users.<br></p><p><br></p><p>The Company reserves the right to remove content that the Company deems inappropriate for any reason what so ever without notice. The Company also reserves the right, in the Company’s sole discretion, to remove a user's privilege to post content on the Site.<br></p><p><br></p><p>The Company does not in any manner endorse the content of its users and cannot and does not vouch for its reliability or otherwise accept liability for it.<br></p><p><br></p><p>Minors (persons under 18 years of age), persons or organizations that cannot enter into binding contracts under applicable law, and those who may be prevented by contractual obligations from entering into binding contracts with Solid Scribe are not allowed to use this Site.<br></p><p><br></p><p>The Company has the right, but not the obligation, to take any of the following actions in the Company’s sole discretion at any time and for any reason without providing you any prior notice:<br></p><p><br></p><p>1. Restrict, suspend, modify or terminate access to the Site or all or any part of the Company’s Services;<br></p><p>2. Change, suspend or discontinue all or any part of the Company’s Services;<br></p><p>3. Refuse, move, modify or remove any material submitted to the Site by any person, for any reason;<br></p><p>4. Refuse, move, modify or remove any content available on the Site;<br></p><p>5. Deactivate or delete your account and all related information and files in your account;<br></p><p>6. Establish, discontinue or change general practices and limits concerning use of the Site and the Company’s Services.<br></p><p><br></p><p>You agree that the Company is not liable to you or any third party for taking any of these actions. Any registration or other eligibility requirements are in the sole discretion of the Company and may be modified for any reason at any time.<br></p><p><br></p><p>YOUR INFORMATION AND CONTENT<br></p><p><br></p><p>Any information you provide to Solid Scribe or other users during your registration or use of the Site (in any public message area, through any mail feature, or otherwise generated out of your use of the Site or the Services), is subject to the following:<br></p><p><br></p><p>(a) You are solely responsible for the content of your information, postings or Notes. The Company reserves the right to take any action with respect to such information that it deems necessary or appropriate in its sole discretion for any reason, including if the Company believes information is inappropriate for the Site or the Services, may create liability for the Company.<br></p><p><br></p><p>(b) You agree that your information will not, to the best of your knowledge: (i) violate any law (including without limitation those governing export control, consumer protection, unfair competition, anti-discrimination or false advertising); or (ii) be libelous, defamatory, obscene, abusive, violate a third party's right to privacy, otherwise violate any applicable local, state, national or international law, amount to spamming or be otherwise inappropriate. You may not post content that degrades others on the basis of gender, race, class, ethnicity, national origin, religion, sexual preference, disability or other classification. Epithets and other language intended to intimidate, unlawfully threaten, unlawfully harass or incite violence are alLine truncated
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -26,24 +26,25 @@ export default new Vuex.Store({
|
||||
localStorage.removeItem('currentVersion')
|
||||
delete axios.defaults.headers.common['authorizationtoken']
|
||||
state.username = null
|
||||
state.userTotals = null
|
||||
},
|
||||
toggleNightMode(state, pastTheme){
|
||||
|
||||
const themes = {
|
||||
'white':{
|
||||
'body_bg_color': '#f5f6f7',
|
||||
'body_bg_color': '#f1f1f1',//'#f5f6f7',
|
||||
'small_element_bg_color': '#fff',
|
||||
'text_color': '#3d3d3d',
|
||||
'dark_border_color': '#DFE1E6',
|
||||
'dark_border_color': '#d9d9d9',//'#DFE1E6',
|
||||
'border_color': '#DFE1E6',
|
||||
'menu-accent': '#cecece',
|
||||
'menu-text': '#5e6268',
|
||||
},
|
||||
'black':{
|
||||
'body_bg_color': '#000',
|
||||
'body_bg_color': '#0f0f0f',//'#000',
|
||||
'small_element_bg_color': '#000',
|
||||
'text_color': '#FFF',
|
||||
'dark_border_color': '#ACACAC', //Lighter color to accent elemnts user can interact with
|
||||
'dark_border_color': '#555',//'#ACACAC', //Lighter color to accent elemnts user can interact with
|
||||
'border_color': '#555',
|
||||
'menu-accent': '#626262',
|
||||
'menu-text': '#d9d9d9',
|
||||
@@ -52,7 +53,7 @@ export default new Vuex.Store({
|
||||
'body_bg_color': '#000',
|
||||
'small_element_bg_color': '#000',
|
||||
'text_color': '#a98457',
|
||||
'dark_border_color': '#a98457',
|
||||
'dark_border_color': '#555',
|
||||
'border_color': '#555',
|
||||
'menu-accent': '#626262',
|
||||
'menu-text': '#a69682',
|
||||
@@ -98,10 +99,6 @@ export default new Vuex.Store({
|
||||
}
|
||||
})(navigator.userAgent||navigator.vendor||window.opera, state);
|
||||
},
|
||||
toggleNoteSettingsPane(state){
|
||||
|
||||
state.isNoteSettingsOpen = !state.isNoteSettingsOpen
|
||||
},
|
||||
setSocketIoSocket(state, socket){
|
||||
|
||||
//Put socket id in axios headers
|
||||
|
||||
+1
-1
@@ -259,7 +259,7 @@ let NoteTest = require('@models/Note')
|
||||
let AuthTest = require('@helpers/Auth')
|
||||
|
||||
Auth.test()
|
||||
UserTest.keyPairTest('genMan25', '1', printResults)
|
||||
UserTest.keyPairTest('genMan30', '1', printResults)
|
||||
.then( ({testUserId, masterKey}) => NoteTest.test(testUserId, masterKey, printResults))
|
||||
.then( message => {
|
||||
if(printResults) console.log(message)
|
||||
|
||||
@@ -32,6 +32,7 @@ Attachment.textSearch = (userId, searchTerm) => {
|
||||
) as snippet
|
||||
FROM attachment
|
||||
WHERE user_id = ?
|
||||
AND visible != 0
|
||||
AND MATCH(text)
|
||||
AGAINST(? IN NATURAL LANGUAGE MODE)
|
||||
LIMIT 1000`
|
||||
|
||||
+85
-25
@@ -42,7 +42,7 @@ Note.test = (userId, masterKey, printResults) => {
|
||||
testNoteId = newNoteId
|
||||
|
||||
return Note.update
|
||||
(userId, testNoteId, 'Note text', 'Test Note beans Title', 0, 0, 0, 'hash', masterKey)
|
||||
(userId, testNoteId, 'Note text', 'Test Note beans barns Title', 0, 0, 0, 'hash', masterKey)
|
||||
|
||||
})
|
||||
.then(() => {
|
||||
@@ -63,14 +63,14 @@ Note.test = (userId, masterKey, printResults) => {
|
||||
|
||||
if(printResults) console.log('Test: Reindex normal note - Pass')
|
||||
|
||||
return Note.encryptedIndexSearch(userId, 'beans', null, masterKey)
|
||||
return Note.encryptedIndexSearch(userId, 'beans barns', null, masterKey)
|
||||
|
||||
})
|
||||
.then(textSearchResults => {
|
||||
|
||||
if(textSearchResults['ids'] && textSearchResults['ids'].length >= 1){
|
||||
if(printResults) console.log('Test: Normal Note Search Index - Pass')
|
||||
} else { console.log('Test: Search Index - Fail') }
|
||||
} else { console.log('Test: Search Index - Fail-------------> 🥱') }
|
||||
|
||||
return ShareNote.addUserToSharedNote(userId, testNoteId, shareUserId, masterKey)
|
||||
})
|
||||
@@ -868,39 +868,98 @@ Note.encryptedIndexSearch = (userId, searchQuery, searchTags, masterKey) => {
|
||||
const decipheredSearchIndex = cs.decrypt(masterKey, row.salt, row.index)
|
||||
const searchIndex = JSON.parse(decipheredSearchIndex)
|
||||
|
||||
//Clean up search word
|
||||
const word = searchQuery.toLowerCase().replace(/[^a-z0-9]/g, '')
|
||||
//Clean up search word, leave in spaces, split to array
|
||||
const words = searchQuery.toLowerCase().replace(/[^a-z0-9 ]/g, '').split(' ')
|
||||
|
||||
let noteIds = []
|
||||
let partials = []
|
||||
Object.keys(searchIndex).forEach(wordIndex => {
|
||||
if( wordIndex.indexOf(word) != -1 && wordIndex != word){
|
||||
partials.push(wordIndex)
|
||||
noteIds.push(...searchIndex[wordIndex])
|
||||
let wordSearchCount = 0;
|
||||
|
||||
|
||||
let partialWords = [] //For debugging
|
||||
let exactWords = [] //For debugging
|
||||
|
||||
|
||||
let exactWordIdSets = []
|
||||
let partialMatchNoteIds = []
|
||||
|
||||
words.forEach(word => {
|
||||
|
||||
//Skip short words
|
||||
if(word.length <= 2){
|
||||
return
|
||||
}
|
||||
|
||||
//count all words being searched
|
||||
wordSearchCount++
|
||||
|
||||
//Save all exact match sets if found
|
||||
if(searchIndex[word]){
|
||||
// exactWords.push(word) //Words for debugging
|
||||
exactWordIdSets.push(...searchIndex[word])
|
||||
}
|
||||
|
||||
//Find all partial word matches in index
|
||||
Object.keys(searchIndex).forEach(wordIndex => {
|
||||
if( wordIndex.indexOf(word) != -1 && wordIndex != word){
|
||||
// partialWords.push(wordIndex) //partialWords for debugging
|
||||
partialMatchNoteIds.push(...searchIndex[wordIndex])
|
||||
}
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
const exactArray = searchIndex[word] ? searchIndex[word] : []
|
||||
//If more than one work was searched, remove notes that don't contain both
|
||||
if(words.length > 1 && exactWordIdSets.length > 0){
|
||||
|
||||
let searchData = {
|
||||
'word':word,
|
||||
'exact': exactArray,
|
||||
'partials': partials,
|
||||
'partial': [...new Set(noteIds) ],
|
||||
//Find ids that appear more than once, this means there was an exact match in more than one note
|
||||
let overlappingIds = exactWordIdSets.filter((e, i, a) => a.indexOf(e) !== i)
|
||||
overlappingIds = [...new Set(overlappingIds)]
|
||||
|
||||
//If there are notes that appear
|
||||
if(overlappingIds.length > 0){
|
||||
exactWordIdSets = overlappingIds
|
||||
}
|
||||
|
||||
//If note appears in partial and exact, show only that set
|
||||
const partialIntersect = exactWordIdSets.filter(x => partialMatchNoteIds.includes(x))
|
||||
if(partialIntersect.length > 0){
|
||||
exactWordIdSets = partialIntersect
|
||||
partialMatchNoteIds = []
|
||||
}
|
||||
}
|
||||
|
||||
//Remove duplicates from final id sets
|
||||
let finalExact = [ ...new Set(exactWordIdSets) ]
|
||||
let finalPartial = [ ...new Set(partialMatchNoteIds) ]
|
||||
|
||||
//Remove exact matches from partials set if there is overlap
|
||||
if(searchData['exact'].length > 0 && searchData['partial'].length > 0){
|
||||
searchData['partial'] = searchData['partial']
|
||||
.filter( ( el ) => !searchData['exact'].includes( el ) )
|
||||
if(finalExact.length > 0 && finalPartial.length > 0){
|
||||
finalPartial = finalPartial
|
||||
.filter( ( el ) => !finalExact.includes( el ) )
|
||||
}
|
||||
|
||||
searchData['ids'] = searchData['exact'].concat(searchData['partial'])
|
||||
searchData['total'] = searchData['ids'].length
|
||||
//Combine the two filtered sets
|
||||
let finalIdSearchSet = finalExact.concat(finalPartial)
|
||||
|
||||
// console.log(searchData['total'])
|
||||
// let searchData = {
|
||||
// 'query':searchQuery,
|
||||
// 'words_count': words.length,
|
||||
// 'exact_matches': exactWordIdSets.length,
|
||||
// 'word_search_count': wordSearchCount,
|
||||
// 'exactWords': exactWords,
|
||||
// 'exact': finalExact,
|
||||
// 'partialWords': partialWords,
|
||||
// 'partial': finalPartial,
|
||||
// }
|
||||
|
||||
return resolve({ 'ids':searchData['ids'] })
|
||||
// //Lump all found note ids into one array
|
||||
// searchData['ids'] = finalIdSearchSet
|
||||
// searchData['total'] = searchData['ids'].length
|
||||
|
||||
// console.log('-----------------')
|
||||
// console.log(searchData)
|
||||
// console.log('-----------------')
|
||||
|
||||
return resolve({ 'ids':finalIdSearchSet })
|
||||
|
||||
|
||||
} else {
|
||||
@@ -971,7 +1030,8 @@ Note.search = (userId, searchQuery, searchTags, fastFilters, masterKey) => {
|
||||
GROUP_CONCAT(DISTINCT attachment.file_location) as thumbs,
|
||||
shareUser.username as shareUsername,
|
||||
note.shared,
|
||||
note.encrypted_share_password_key
|
||||
note.encrypted_share_password_key,
|
||||
note.indexed
|
||||
FROM note
|
||||
JOIN note_raw_text ON (note_raw_text.id = note.note_raw_text_id)
|
||||
LEFT JOIN note_tag ON (note.id = note_tag.note_id)
|
||||
|
||||
Reference in new issue
Block a user