diff --git a/.env.development b/.env.development index 77ae56f..e032ebc 100644 --- a/.env.development +++ b/.env.development @@ -1,4 +1,4 @@ -APP_VERSION="DEV 0.0.10" +APP_VERSION="DEV 0.0.27" SERVICE_WORKER_FILE='service-worker.js' APP_ID='1' APP_URL='https://freeplanet.app' diff --git a/.gitignore b/.gitignore index d03be54..b327f0b 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,9 @@ .thumbs.db .env .env.production +.env.production.bak +.env.prod.bak +.env.test node_modules /dist /src-cordova/node_modules @@ -28,4 +31,6 @@ coverage /_PROVE /_LOCALE deploy.sh -deploy_production.sh +deploy_on_production.sh +deploy_on_test_server.sh +send_to_production.sh diff --git a/package.json b/package.json index 4bdad00..cb30e46 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,7 @@ "serve": "quasar serve ./dist/pwa-mat", "serve:coverage": "quasar serve test/coverage/lcov-report/ --cache 0 --port 8788", "deploy": "deploy.sh", + "deploy_server_test": "NODE_ENV=test quasar build -m pwa", "generate-sw": "workbox generateSW workbox-config.js" }, "dependencies": { diff --git a/quasar.conf.js b/quasar.conf.js index 3dbbc0d..815f50a 100644 --- a/quasar.conf.js +++ b/quasar.conf.js @@ -195,6 +195,7 @@ module.exports = function (ctx) { }, manifest: { name: 'Free Planet', + version: '0.0.14', short_name: 'freeplanet', description: 'Social project in order to connecting people each others (working in progress...)', display: 'standalone', diff --git a/src-pwa/custom-service-worker.js b/src-pwa/custom-service-worker.js index c1cdaa1..43ee1de 100644 --- a/src-pwa/custom-service-worker.js +++ b/src-pwa/custom-service-worker.js @@ -1,4 +1,3 @@ - /* * This file (which will be your service worker) * is picked up by the build system ONLY if @@ -7,49 +6,49 @@ // Questo è il swSrc -console.log('SW-06 ___________________________ PAO: this is my custom service worker'); +console.log(' [ VER-0.0.27 ] _---------________------ PAO: this is my custom service worker'); -importScripts('https://storage.googleapis.com/workbox-cdn/releases/3.0.0/workbox-sw.js'); //++Todo: Replace with local workbox.js importScripts('../statics/js/idb.js'); importScripts('../statics/js/storage.js'); +importScripts('https://storage.googleapis.com/workbox-cdn/releases/3.0.0/workbox-sw.js'); //++Todo: Replace with local workbox.js -console.log('SW-06 1'); +let port = 3000; +if (self.location.hostname === 'test.freeplanet.app') { + port = 3001; +} +// console.log('SW-06 1'); const cfgenv = { - serverweb: self.location.protocol + "//" + self.location.hostname + ':3000', + serverweb: self.location.protocol + "//" + self.location.hostname + ':' + port, dbname: 'mydb3', dbversion: 11, } -console.log('SW-06 2'); - -console.log('SERVERWEB=', cfgenv.serverweb) - // console.log('serverweb', cfgenv.serverweb) + async function writeData(table, data) { - console.log('writeData', table, data); + // console.log('writeData', table, data); await idbKeyval.setdata(table, data); } async function readAllData(table) { - console.log('readAllData', table); + // console.log('readAllData', table); return await idbKeyval.getalldata(table); } async function clearAllData(table) { - console.log('clearAllData', table); + // console.log('clearAllData', table); await idbKeyval.clearalldata(table) } async function deleteItemFromData(table, id) { - console.log('deleteItemFromData', table, 'ID:', id); + // console.log('deleteItemFromData', table, 'ID:', id); await idbKeyval.deletedata(table, id) } - // self.addEventListener('activate', function(event) { // event.waitUntil( // // createDB() @@ -58,10 +57,10 @@ async function deleteItemFromData(table, id) { if (!workbox) { let workbox = new self.WorkboxSW(); - console.log('SW-06 3'); } if (workbox) { + // console.log('WORKBOX PRESENT') // const url = new URL(location.href); // const debug = url.searchParams.has('debug'); const debug = false; @@ -105,37 +104,81 @@ if (workbox) { }) ); + // console.log(' routing.registerRoute function declaration:') workbox.routing.registerRoute( new RegExp(cfgenv.serverweb + '/todos/'), function (args) { - console.log('registerRoute!') + console.log('registerRoute! ', cfgenv.serverweb + '/todos/') + // console.log('DATABODY:', args.event.request.body) + let myres = null + // return fetch(args.event.request, args.event.headers) return fetch(args.event.request, args.event.headers) .then(function (res) { - console.log('1° ******* [[[ SERVICE-WORKER ]]] registerRoute fetch: ', args.event) + myres = res + // console.log('1° ******* [[[ SERVICE-WORKER ]]] registerRoute fetch: -> ', args.event.request, res) // LOAD FROM SERVER , AND SAVE INTO INDEXEDDB - console.log('res.status', res.status) + // console.log('res.status', res.status) if (res.status === 200) { - var clonedRes = res.clone(); - clearAllData('todos') - .then(function () { - return clonedRes.json(); + const clonedRes = res.clone(); + + return clearAllData('todos') + .then(() => { + return clonedRes }) - .then(function (data) { - if (data.todos) { - console.log('Records TODOS Received from Server [', data.todos.length, 'record]', data.todos) - for (let key in data.todos) { - writeData('todos', data.todos[key]) - } - } - }); - return res } }) - } - ); + .then((clonedRes) => { + if (clonedRes !== undefined) + return clonedRes.json(); + return null + }) + .then(async data => { + if (data) { + if (data.todos) { + console.log('***********************+++++++++++++++++++++++++++++++++++++++++++++++++++********** Records TODOS Received from Server [', data.todos.length, 'record]', data.todos) + for (const key in data.todos) { + await writeData('todos', data.todos[key]) + } + } + } + }) + .then(() => { + return myres + }) + .catch(err => { + console.log('ERROR registerRoute FETCH:', err) + return myres + }) + }) + workbox.routing.registerRoute(function (routeData) { + return (routeData.event.request.headers.get('accept').includes('text/html')); + }, function (args) { + return caches.match(args.event.request) + .then(function (response) { + if (response) { + return response; + } else { + return fetch(args.event.request) + .then(function (res) { + return caches.open('dynamic') + .then(function (cache) { + cache.put(args.event.request.url, res.clone()); + return res; + }) + }) + .catch(function (err) { + return caches.match('/offline') + .then(function (res) { + return res; + }); + }); + } + }) + }); + workbox.routing.registerRoute( new RegExp(/.*\/(?:statics\/icons).*$/), workbox.strategies.cacheFirst({ @@ -225,16 +268,17 @@ if (workbox) { if ('serviceWorker' in navigator) { - console.log('***************** Entering in custom-service-worker.js:') + // console.log('***************** Entering in custom-service-worker.js:') } -self.addEventListener('fetch', (event) => { - if (event.request.url === '/') { - const staleWhileRevalidate = new workbox.strategies.StaleWhileRevalidate(); - event.respondWith(staleWhileRevalidate.handle({event})); - } -}); + +// self.addEventListener('fetch', (event) => { +// if (event.request.url === '/') { +// const staleWhileRevalidate = new workbox.strategies.StaleWhileRevalidate(); +// event.respondWith(staleWhileRevalidate.handle({ event })); +// } +// }); // self.addEventListener('fetch', function (event) { // console.log('[Service Worker] Fetching something ....', event); @@ -245,7 +289,7 @@ self.addEventListener('fetch', (event) => { // } // event.respondWith(caches.match(event.request)); // }); - +// // const syncStore = {} // self.addEventListener('message', event => { @@ -259,77 +303,124 @@ self.addEventListener('fetch', (event) => { // console.log(event.data) // }) -self.addEventListener('sync', function (event) { - console.log('[Service Worker V5] Background syncing', event.tag); +// addEventListener('fetch', event => { +// // Prevent the default, and handle the request ourselves. +// event.respondWith(async function() { +// // Try to get the response from a cache. +// const cachedResponse = await caches.match(event.request); +// // Return it if we found one. +// if (cachedResponse && (event.request.cache !== 'no-cache')) +// return cachedResponse; +// +// // If we didn't find a match in the cache, use the network. +// return fetch(event.request); +// }()); +// }); - let mystrparam = event.tag - let multiparams = mystrparam.split('|') - if (multiparams) { - if (multiparams.length > 3) { - let cmd = multiparams[0] - let table = multiparams[1] - let method = multiparams[2] - let token = multiparams[3] - // let lang = multiparams[3] +// self.addEventListener('fetch', function (event) { +// event.respondWith( +// caches.match(event.request).then(function (response) { +// return response || +// fetch(event.request, event.headers) +// .catch(err => { +// console.log('_______________________ ERRORE FETCH SW: ', event.request, err) +// writeData('config', { _id: 2, stateconn: 'offline' }) +// return caches.match(event.request); +// }) +// }) +// ); +// }); - if (cmd === 'sync-todos') { - console.log('[Service Worker] Syncing', cmd, table, method); - const headers = new Headers() - headers.append('content-Type', 'application/json') - headers.append('Accept', 'application/json') - headers.append('x-auth', token) +// self.addEventListener('fetch', function (event) { +// event.respondWith( +// fetch(event.request, event.headers) +// .catch(err => { +// console.log('_______________________ ERRORE FETCH SW: ', event.request, err) +// writeData('config', {_id: 2, stateconn: 'offline'}) +// return caches.match(event.request); +// }) +// ); +// }); - console.log('A1) INIZIO.............................................................'); - event.waitUntil( - readAllData(table) - .then(function (alldata) { - const myrecs = [...alldata] - console.log('----------------------- LEGGO QUALCOSA DAL WAITUNTIL ') - if (myrecs) { - for (let rec of myrecs) { - //console.log('syncing', table, '', rec.descr) - let link = cfgenv.serverweb + '/todos' - - if (method !== 'POST') - link += '/' + rec._id - - console.log('++++++++++++++++++ SYNCING !!!! ', rec.descr, table, 'FETCH: ', method, link, 'data:') - - // Insert/Delete/Update table to the server - fetch(link, { - method: method, - headers: headers, - mode: 'cors', // 'no-cors', - body: JSON.stringify(rec) - }) - .then(function (resData) { - // console.log('Result CALL ', method, ' OK? =', resData.ok); - - // Anyway Delete this, otherwise in some cases will return error, but it's not a problem. - // for example if I change a record and then I deleted ... - // if (resData.ok) { - deleteItemFromData(table, rec._id); - // } - - console.log('DELETE: ', mystrparam) - deleteItemFromData('swmsg', mystrparam) - - }) - .catch(function (err) { - console.log('!!!!!!!!!!!!!!! Error while sending data', err); - }); - } - } - }) - ); - console.log('A2) ?????????????????????????? ESCO DAL LOOP !!!!!!!!! err=') - } - } - } -}) -; +// self.addEventListener('sync', function (event) { +// console.log('[Service Worker V5] Background syncing', event.tag); +// +// let mystrparam = event.tag +// let multiparams = mystrparam.split('|') +// if (multiparams) { +// if (multiparams.length > 3) { +// let cmd = multiparams[0] +// let table = multiparams[1] +// let method = multiparams[2] +// let token = multiparams[3] +// // let lang = multiparams[3] +// +// if (cmd === 'sync-todos') { +// console.log('[Service Worker] Syncing', cmd, table, method); +// +// const headers = new Headers() +// headers.append('content-Type', 'application/json') +// headers.append('Accept', 'application/json') +// headers.append('x-auth', token) +// +// +// // console.log('A1) INIZIO.............................................................'); +// +// event.waitUntil( +// readAllData(table) +// .then(function (alldata) { +// const myrecs = [...alldata] +// console.log('----------------------- LEGGO QUALCOSA DAL WAITUNTIL ') +// let errorfromserver = false +// if (myrecs) { +// for (let rec of myrecs) { +// //console.log('syncing', table, '', rec.descr) +// let link = cfgenv.serverweb + '/todos' +// +// if (method !== 'POST') +// link += '/' + rec._id +// +// console.log('++++++++++++++++++ SYNCING !!!! ', rec.descr, table, 'FETCH: ', method, link, 'data:') +// +// // console.log('DATATOSAVE:', JSON.stringify(rec)) +// +// // Insert/Delete/Update table to the server +// fetch(link, { +// method: method, +// headers: headers, +// cache: 'no-cache', +// mode: 'cors', // 'no-cors', +// body: JSON.stringify(rec) +// }) +// .then(() => { +// deleteItemFromData(table, rec._id) +// }) +// .then(() => { +// deleteItemFromData('swmsg', mystrparam) +// }) +// .catch(function (err) { +// console.log('!!!!!!!!!!!!!!! Error while sending data', err, err.message); +// if (err.message === 'Failed to fetch') { +// errorfromserver = true +// } +// }) +// } +// return errorfromserver +// } +// }) +// .then((errorfromserver) => { +// const mystate = !errorfromserver ? 'online' : 'offline' +// writeData('config', { _id: 2, stateconn: mystate }) +// }) +// ); +// // console.log('A2) ?????????????????????????? ESCO DAL LOOP !!!!!!!!! err=') +// } +// } +// } +// }) +// ; /* @@ -360,7 +451,7 @@ self.addEventListener('sync', event => { }) */ -self.addEventListener('notificationclick', function(event) { +self.addEventListener('notificationclick', function (event) { var notification = event.notification; var action = event.action; @@ -373,8 +464,8 @@ self.addEventListener('notificationclick', function(event) { console.log(action); event.waitUntil( clients.matchAll() - .then(function(clis) { - var client = clis.find(function(c) { + .then(function (clis) { + var client = clis.find(function (c) { return c.visibilityState === 'visible'; }); @@ -390,30 +481,39 @@ self.addEventListener('notificationclick', function(event) { } }); -self.addEventListener('notificationclose', function(event) { +self.addEventListener('notificationclose', function (event) { console.log('Notification was closed', event); }); -self.addEventListener('push', function(event) { +self.addEventListener('push', function (event) { console.log('Push Notification received', event); - var data = {title: 'New!', content: 'Something new happened!', openUrl: '/'}; + var data = { title: 'New!', content: 'Something new happened!', url: '/' }; - if (event.data) { - data = JSON.parse(event.data.text()); - } + try { - var options = { - body: data.content, - icon: '/statics/icons/android-chrome-192x192.png', - badge: '/statics/icons/android-chrome-192x192.png', - data: { - url: data.openUrl + if (event.data) { + try { + data = JSON.parse(event.data.text()); + } catch (e) { + data = event.data.text(); + } } - }; - event.waitUntil( - self.registration.showNotification(data.title, options) - ); + var options = { + body: data.content, + icon: '/statics/icons/android-chrome-192x192.png', + badge: '/statics/icons/android-chrome-192x192.png', + data: { + url: data.url + } + }; + + event.waitUntil( + self.registration.showNotification(data.title, options) + ); + } catch (e) { + console.log('Error on event push:', e) + } }); diff --git a/src/App.ts b/src/App.ts index 3fa8cf6..3ce9f38 100644 --- a/src/App.ts +++ b/src/App.ts @@ -12,7 +12,6 @@ import globalroutines from './globalroutines/index' import { GlobalStore } from './store/Modules' - @Component({ components: { appHeader: Header @@ -23,9 +22,9 @@ import { GlobalStore } from './store/Modules' export default class App extends Vue { public backgroundColor = 'whitesmoke' - public isSubscribed = false public $q + public listaRoutingNoLogin = ['/vreg?', '/offline'] created() { if (process.env.DEV) { @@ -37,19 +36,35 @@ export default class App extends Vue { // console.info(process.env) } - UserStore.actions.autologin() - .then((loginEseguito) => { - if (loginEseguito) { - globalroutines(this, 'loadapp', '') - // this.$router.replace('/') + // Make autologin only if some routing + + // console.log('window.location.href', window.location.href) + + let chiamaautologin = true + this.listaRoutingNoLogin.forEach(mystr => { + if (window.location.href.includes(mystr)) { + chiamaautologin = false + } + }) + + if (chiamaautologin) { + console.log('CHIAMA autologin_FromLocalStorage') + UserStore.actions.autologin_FromLocalStorage() + .then((loadstorage) => { + if (loadstorage) { + globalroutines(this, 'loadapp', '') + // this.$router.replace('/') // Create Subscription to Push Notification - GlobalStore.actions.createPushSubscription() - } - }) + GlobalStore.actions.createPushSubscription() + } + }) + } + + // Calling the Server for updates ? + // Check the verified_email } - } diff --git a/src/common/axios.ts b/src/common/axios.ts index 89ffac5..9986156 100644 --- a/src/common/axios.ts +++ b/src/common/axios.ts @@ -5,6 +5,7 @@ import { AxiosResponse } from 'axios' import { default as VueRouter } from 'vue-router' +import { serv_constants } from "@src/store/Modules/serv_constants" // import { TokenHelper } from "./token-helper"; let initialized: boolean = false @@ -54,7 +55,7 @@ export function UseAxios(router: VueRouter) { } } - if (response.status === 403 && handle(response.status, exclude)) { + if (response.status === serv_constants.RIS_CODE__HTTP_FORBIDDEN_INVALID_TOKEN && handle(response.status, exclude)) { window.setTimeout(() => router.replace('/forbidden'), 200) } diff --git a/src/components/Header.vue b/src/components/Header.vue index 7d2557b..049b2ae 100644 --- a/src/components/Header.vue +++ b/src/components/Header.vue @@ -32,6 +32,17 @@
{{$t('msg.myDescriz')}} {{ getAppVersion() }}
+ + + + + -
+
+ class="myexpired" + format="DD/MM/YY" + @change="val => { model = val }" > +
+
+ + + + + + +
- + diff --git a/src/components/todos/SubMenus/SubMenus.scss b/src/components/todos/SubMenus/SubMenus.scss index 6cbbff6..d524555 100644 --- a/src/components/todos/SubMenus/SubMenus.scss +++ b/src/components/todos/SubMenus/SubMenus.scss @@ -3,7 +3,7 @@ } -.item-menu{ +.item-menu { font-size: 1rem; } @@ -11,6 +11,7 @@ cursor: pointer; } -.menuProgress { - +.menuInputProgress > div:nth-child(2) > div > input { + min-width: 30px; + width: 30px; } diff --git a/src/components/todos/SubMenus/SubMenus.ts b/src/components/todos/SubMenus/SubMenus.ts index 2f18756..ffde880 100644 --- a/src/components/todos/SubMenus/SubMenus.ts +++ b/src/components/todos/SubMenus/SubMenus.ts @@ -2,8 +2,8 @@ import Vue from 'vue' import { Component, Prop } from 'vue-property-decorator' import { ITodo } from '../../../model/index' -import { rescodes } from "@src/store/Modules/rescodes" -import { UserStore } from "@store" +import { rescodes } from '@src/store/Modules/rescodes' +import { UserStore } from '@store' @Component({ @@ -14,7 +14,7 @@ export default class SubMenus extends Vue { public selectPriority: [] = rescodes.selectPriority[UserStore.state.lang] @Prop({ required: false }) menuPopupTodo: any[] - @Prop({ required: false }) itemtodo: ITodo[] + @Prop({ required: false }) itemtodo: ITodo $q: any clickMenu (field) { @@ -25,6 +25,15 @@ export default class SubMenus extends Vue { this.$emit('setPriority', field) } + KeychangeProgress (e) { + if (this.itemtodo.progress > 100) { + this.itemtodo.progress = 100 + } + if (this.itemtodo.progress < 0) { + this.itemtodo.progress = 0 + } + } + create () { this.selectPriority = rescodes.selectPriority[UserStore.state.lang] diff --git a/src/components/todos/SubMenus/SubMenus.vue b/src/components/todos/SubMenus/SubMenus.vue index 73c166d..51de6d1 100644 --- a/src/components/todos/SubMenus/SubMenus.vue +++ b/src/components/todos/SubMenus/SubMenus.vue @@ -18,14 +18,28 @@ - + + - -
- {{$parent.percentageProgress}}% + +
+
+ + + + + + @@ -61,6 +75,6 @@ - diff --git a/src/components/todos/todo/todo.ts b/src/components/todos/todo/todo.ts index cc35885..36e1a2e 100644 --- a/src/components/todos/todo/todo.ts +++ b/src/components/todos/todo/todo.ts @@ -20,7 +20,7 @@ import VueIdb from 'vue-idb' import globalroutines from '../../../globalroutines/index' import $ from 'jquery' -import Api from "@api" +import Api from '@api' @Component({ @@ -43,6 +43,9 @@ export default class Todo extends Vue { itemDragEnd: any = null selrowid: number = 0 polling = null + mytypetransgroup: string = 'flip-list' + tmpstrTodos: string = '' + loadDone: boolean = false fieldtochange: String [] = ['descr', 'completed', 'category', 'expiring_at', 'priority', 'id_prev', 'id_next', 'pos', 'enableExpiring', 'progress'] @@ -65,7 +68,10 @@ export default class Todo extends Vue { @Watch('$route.params.category') changecat() { // console.log('changecat') - this.load() + this.mytypetransgroup = 'nessuno' + this.updatetable(false, '$route.params.category').then(() => { + this.mytypetransgroup = 'crossfade' + }) } get todos_changed() { @@ -76,23 +82,31 @@ export default class Todo extends Vue { return Todos.state.reload_fromServer } + set reload_fromServer(value: number) { + Todos.state.reload_fromServer = value + } + @Watch('todos_changed', { immediate: true, deep: true }) - changetodos_changed(value: string, oldValue: string) { + changetodos_changed(value: number, oldValue: number) { - this.$q.notify('Changed...') + // this.$q.notify('Changed...') - // console.log('Todos.state.todos_changed CHANGED!', value, oldValue) - this.updatetable(true) + if ((value > 1) && (this.loadDone)) { + // console.log('Todos.state.todos_changed CHANGED!', value, oldValue) + this.updatetable(true, 'todos_changed') + } } @Watch('reload_fromServer', { immediate: true }) - reload_fromServer_changed(value: string, oldValue: string) { - console.log('reload_fromServer_changed!', value, oldValue) - // if (value) { - Todos.actions.dbLoadTodo(false) + reload_fromServer_changed(value: number, oldValue: number) { + if (value > 0) { + // console.log('reload_fromServer_changed!', value, oldValue) + // if (value) { + Todos.actions.dbLoadTodo(false) - Todos.actions.updateArrayInMemory() + Todos.actions.updateArrayInMemory() + } // } } @@ -104,7 +118,37 @@ export default class Todo extends Vue { @Watch('testPao', { immediate: true, deep: true }) changedTestpao(value: string, oldValue: string) { // console.log('testpao CHANGED', value, oldValue) - this.updatetable(true) + // this.updatetable(true, 'testPao') + } + + getArrTodos() { + + let mystr = '' + let mythis = this + + mythis.tmpstrTodos = '' + globalroutines(null, 'readall', 'todos', null) + .then(function (alldata) { + const myrecs = [...alldata] + + myrecs.forEach(rec => { + mystr = mystr + rec.descr + '] [' + }) + + mythis.tmpstrTodos = 'TODOS: ' + mystr + }) + } + + setArrTodos() { + + let mystr = '' + let mythis = this + + mythis.tmpstrTodos = '' + globalroutines(null, 'write', 'todos', this.todos_arr[0]) + .then(function (alldata) { + mythis.getArrTodos() + }) } getCategory() { @@ -279,7 +323,7 @@ export default class Todo extends Vue { // Updated only elements modified await this.updateModifyRecords(true) - this.updatetable() + this.updatetable(false, 'onEnd') } @@ -295,7 +339,7 @@ export default class Todo extends Vue { }) if (update) - await this.updatetable(refresh) + await this.updatetable(refresh, 'updateModifyRecords') } @@ -318,7 +362,8 @@ export default class Todo extends Vue { async load() { - this.todos_arr = [...Todos.state.todos] + + // this.todos_arr = [...Todos.state.todos] // Set last category selected localStorage.setItem(rescodes.localStorage.categorySel, this.getCategory()) @@ -330,17 +375,13 @@ export default class Todo extends Vue { this.setarrPriority() this.clearArr() - await this.updatetable() + await this.updatetable(false, 'load') this.checkUpdate_everytime() - /* - this.todos_arr.forEach((elem, index) => { - this.logelem('LOAD ' + index, elem) - }) - */ + this.loadDone = true } // Call to check if need to refresh @@ -350,24 +391,11 @@ export default class Todo extends Vue { }, 10000) } - copy(o) { - let output, v, key - output = Array.isArray(o) ? [] : {} - for (key in o) { - v = o[key] - output[key] = (typeof v === 'object') ? this.copy(v) : v - } - return output - } - - initcat() { + let tomorrow = new Date(); + tomorrow.setDate(tomorrow.getDate() + 1) - let mydatenow = new Date().getDate() - let mydateexp = new Date().getDate() + 10 - - console.log('User:' + UserStore.state.userId) const objtodo: ITodo = { // _id: new Date().toISOString(), // Create NEW @@ -376,11 +404,11 @@ export default class Todo extends Vue { descr: '', priority: rescodes.Todos.PRIORITY_NORMAL, completed: false, - created_at: mydatenow, - modify_at: mydatenow, - completed_at: 0, + created_at: new Date(), + modify_at: new Date(), + completed_at: new Date(), category: '', - expiring_at: mydateexp, + expiring_at: tomorrow, enableExpiring: false, id_prev: '', id_next: '', @@ -388,7 +416,8 @@ export default class Todo extends Vue { modified: false, progress: 0 } - return this.copy(objtodo) + // return this.copy(objtodo) + return objtodo } @@ -417,8 +446,6 @@ export default class Todo extends Vue { const objtodo = this.initcat() - console.log('insertTodo ', UserStore.state.userId) - objtodo.descr = this.todo objtodo.category = this.getCategory() const lastelem: ITodo = this.getLastList() @@ -432,30 +459,18 @@ export default class Todo extends Vue { return } - await globalroutines(this, 'write', 'todos', objtodo) - .then((id) => { - console.log('*** IDNEW (3) = ', id) + const id = await globalroutines(this, 'write', 'todos', objtodo) + // update also the last elem + if (lastelem !== null) { + lastelem.id_next = id + // lastelem.modified = true + // console.log('calling MODIFY 4', lastelem) + } - // update also the last elem - if (lastelem !== null) { - lastelem.id_next = id - // lastelem.modified = true - console.log('calling MODIFY 4', lastelem) - } + const rismod = await this.modify(lastelem, false) - this.modify(lastelem, false) - .then(ris => { - console.log('END calling MODIFY 4') - - this.saveItemToSyncAndDb(rescodes.DB.TABLE_SYNC_TODOS, 'POST', objtodo, true) - this.updatetable(false) - - }) - - - }).catch(err => { - console.log('Errore: ' + err.message) - }) + this.saveItemToSyncAndDb(rescodes.DB.TABLE_SYNC_TODOS, 'POST', objtodo, true) + this.updatetable(false, 'insertTodo') // console.log('ESCO.........') @@ -474,17 +489,17 @@ export default class Todo extends Vue { cmdSw = rescodes.DB.CMD_SYNC_TODOS } - if (process.env.DEV) { - console.log('serviceWorker ', ('serviceWorker' in navigator) ? 'PRESENT!' : 'DOESN\'T EXIST!') - console.log('SyncManager ', ('SyncManager' in window) ? 'PRESENT!' : 'DOESN\'T EXIST!') - } + // if (process.env.DEV) { + // console.log('serviceWorker ', ('serviceWorker' in navigator) ? 'PRESENT!' : 'DOESN\'T EXIST!') + // console.log('SyncManager ', ('SyncManager' in window) ? 'PRESENT!' : 'DOESN\'T EXIST!') + // } const mythis = this if ('serviceWorker' in navigator) { await navigator.serviceWorker.ready .then(function (sw) { // _id: new Date().toISOString(), - console.log('---------------------- navigator.serviceWorker.ready') + // console.log('---------------------- navigator.serviceWorker.ready') // mythis.sendMessageToSW(item, method) @@ -495,20 +510,20 @@ export default class Todo extends Vue { }) const sep = '|' - let multiparams = cmdSw + sep + table + sep + method + sep + UserStore.state.idToken + sep + UserStore.state.lang + let multiparams = cmdSw + sep + table + sep + method + sep + UserStore.state.x_auth_token + sep + UserStore.state.lang let mymsgkey = { _id: multiparams, value: multiparams } globalroutines(mythis, 'write', 'swmsg', mymsgkey, multiparams) .then(ris => { - if ('SyncManager' in window) { - console.log(' SENDING... sw.sync.register', multiparams) - return sw.sync.register(multiparams) - } else { + // if ('SyncManager' in window) { + // console.log(' SENDING... sw.sync.register', multiparams) + // return sw.sync.register(multiparams) + // } else { // #Todo ++ Alternative 2 to SyncManager Api.syncAlternative(multiparams) - } + // } }) .then(function () { @@ -541,12 +556,12 @@ export default class Todo extends Vue { } async saveItemToSyncAndDb(table: String, method, item: ITodo, update: boolean) { - return await this.cmdToSyncAndDb(rescodes.DB.CMD_SYNC_NEW_TODOS, table, method, item, 0, 'Your Post was saved for syncing!', update) + return await this.cmdToSyncAndDb(rescodes.DB.CMD_SYNC_NEW_TODOS, table, method, item, 0, '', update) } deleteItemToSyncAndDb(table: String, item: ITodo, id, update: boolean) { - return this.cmdToSyncAndDb(rescodes.DB.CMD_DELETE_TODOS, table, 'DELETE', item, id, 'Your Post was canceled for syncing!', update) + return this.cmdToSyncAndDb(rescodes.DB.CMD_DELETE_TODOS, table, 'DELETE', item, id, '', update) } /* @@ -604,13 +619,13 @@ export default class Todo extends Vue { // Delete item await globalroutines(this, 'delete', 'todos', null, id) .then((ris) => { - mythis.updatetable() + mythis.updatetable(false, 'deleteitem') }).catch((error) => { console.log('err: ', error) }) } - console.log('FINE deleteitem') + // console.log('FINE deleteitem') } getElem(myarray: ITodo[], id) { @@ -625,13 +640,17 @@ export default class Todo extends Vue { return itemnew.pos !== itemold.pos } - async updatetable(refresh: boolean = false) { - // console.log('updatetable') + async updatetable(refresh: boolean = false, strpos = '') { + console.log('updatetable', strpos) this.prevRecords = [...this.todos_arr] return await Todos.actions.getTodosByCategory(this.getCategory()) - .then(arrtemp => { + .then(arrris => { + + this.todos_arr = [] + + let arrtemp = [...arrris] arrtemp = _.orderBy(arrtemp, ['completed', 'priority', 'pos'], ['asc', 'desc', 'asc']) @@ -646,6 +665,8 @@ export default class Todo extends Vue { this.todos_arr = [...arrtemp] // make copy + console.log('AGGIORNA todos_arr') + }) } @@ -729,7 +750,7 @@ export default class Todo extends Vue { } updateitem(myobj) { - console.log('updateitem') + console.log('calling MODIFY 4 updateitem') this.modify(myobj, true) } @@ -777,8 +798,10 @@ export default class Todo extends Vue { // } modifyField(recOut, recIn, field) { - if (recOut[field] !== recIn[field]) { - console.log('*************** CAMPO ', field, 'MODIFICATO!', recOut[field], recIn[field]) + if (String(recOut[field]) !== String(recIn[field])) { + console.log('*************** CAMPO ', field, 'MODIFICATO!') + console.log(recOut[field]) + console.log(recIn[field]) recOut.modified = true recOut[field] = recIn[field] return true @@ -822,7 +845,7 @@ export default class Todo extends Vue { // console.log('SET MODIFIED FALSE') if (update) - this.updatetable(false) + this.updatetable(false, 'modify') }) }) @@ -843,7 +866,7 @@ export default class Todo extends Vue { } clicktest2() { - this.updatetable(false) + this.updatetable(false, 'clicktest') console.log('Todos.state.todos', Todos.state.todos) } diff --git a/src/components/todos/todo/todo.vue b/src/components/todos/todo/todo.vue index eb221c3..0eedb26 100644 --- a/src/components/todos/todo/todo.vue +++ b/src/components/todos/todo/todo.vue @@ -12,7 +12,7 @@
- +
@@ -35,15 +35,24 @@ :after="[{icon: 'arrow_forward', content: true, handler () {}}]" v-on:keyup.enter="insertTodo"/> - - - + -
- - - -
+ + + + + + + + + + + + + + + +
diff --git a/src/css/themes/common.variables.styl b/src/css/themes/common.variables.styl index 4d659aa..6b8b26a 100644 --- a/src/css/themes/common.variables.styl +++ b/src/css/themes/common.variables.styl @@ -23,3 +23,4 @@ $positive = #21BA45 $negative = #DB2828 $info = #31CCEC $warning = #F2C037 + diff --git a/src/globalroutines/indexdb.js b/src/globalroutines/indexdb.js index 00e7d3b..e647dce 100644 --- a/src/globalroutines/indexdb.js +++ b/src/globalroutines/indexdb.js @@ -1,4 +1,4 @@ -import store from '../store' +import store, { GlobalStore } from '../store' import _ from 'lodash' import { UserStore, Todos } from '@store' import { i18n } from '../plugins/i18n' @@ -10,7 +10,7 @@ function saveConfigIndexDb(context) { let data = [] data['_id'] = 1 data['lang'] = UserStore.state.lang - data['token'] = UserStore.state.idToken + data['token'] = UserStore.state.x_auth_token data['userId'] = UserStore.state.userId writeConfigIndexDb('config', data) @@ -73,6 +73,8 @@ export default async (context, cmd, table, datakey = null, id = '') => { return await storage.getdata(table, id) } else if (cmd === 'delete') { return await storage.deletedata(table, id) + } else if (cmd === 'clearalldata') { + return await storage.clearalldata(table) } else if (cmd === 'log') { consolelogpao(table) } diff --git a/src/js/storage.js b/src/js/storage.js index acdeed1..9905be7 100644 --- a/src/js/storage.js +++ b/src/js/storage.js @@ -1,5 +1,6 @@ export let idbKeyval = (() => { let db; + const fieldsData = ['completed_at', 'created_at', 'expiring_at', 'modify_at'] function getDB() { if (!db) { @@ -29,7 +30,7 @@ export let idbKeyval = (() => { return db; } - async function withStore(type, table, callback, ) { + async function withStore(type, table, callback,) { const db = await getDB(); return new Promise((resolve, reject) => { const transaction = db.transaction(table, type); @@ -47,14 +48,18 @@ export let idbKeyval = (() => { }); return req.result; }, + jsonCopy(src) { + return JSON.parse(JSON.stringify(src)); + }, + async getdata(table, key) { let req; await withStore('readonly', table, store => { - console.log('store', store, 'key', key) + console.log('getdata', table, key) req = store.get(key); }); - // console.log('RISFINALE!', req.result) + return req.result; }, async getalldata(table) { @@ -80,9 +85,9 @@ export let idbKeyval = (() => { }, async setdata(table, value) { let req; - console.log('setdata', table, value) - await withStore('readwrite', table, store => { + // console.log('setdata', table, value) + await withStore('readwrite', table, store => { req = store.put(value); }); return req.result; @@ -98,6 +103,7 @@ export let idbKeyval = (() => { }); }, async clearalldata(table) { + // console.log('clearalldata', table) return await withStore('readwrite', table, store => { store.clear(); }); diff --git a/src/layouts/drawer/drawer.vue b/src/layouts/drawer/drawer.vue index 0452d8f..b40dec6 100644 --- a/src/layouts/drawer/drawer.vue +++ b/src/layouts/drawer/drawer.vue @@ -102,7 +102,7 @@ } get Verificato() { - return UserStore.state.verifiedEmail + return UserStore.state.verified_email } get Email() { @@ -111,6 +111,7 @@ logoutHandler() { UserStore.actions.logout() + this.$router.push('/signin') this.$q.notify(this.$t('logout.uscito')) } } diff --git a/src/model/GlobalStore.ts b/src/model/GlobalStore.ts index 32b0fff..ee9ebc8 100644 --- a/src/model/GlobalStore.ts +++ b/src/model/GlobalStore.ts @@ -2,15 +2,19 @@ export interface IPost { title: string } +export type StateConnection = 'online' | 'offline' + export interface IGlobalState { conta: number - isSubscribed: boolean + wasAlreadySubOnDb: boolean + wasAlreadySubscribed: boolean isLoginPage: boolean layoutNeeded: boolean mobileMode: boolean menuCollapse: boolean leftDrawerOpen: boolean category: string + stateConnection: string posts: IPost[] listatodo: ITodoList[] } diff --git a/src/model/Todos.ts b/src/model/Todos.ts index 0243a45..0634125 100644 --- a/src/model/Todos.ts +++ b/src/model/Todos.ts @@ -5,10 +5,10 @@ export interface ITodo { descr?: string, priority: number, completed: boolean, - created_at: any, - modify_at: any, - completed_at: any, - expiring_at: any, + created_at: Date, + modify_at: Date, + completed_at: Date, + expiring_at: Date, enableExpiring?: boolean, id_prev?: string, id_next?: string, @@ -22,7 +22,7 @@ export interface ITodosState { networkDataReceived: boolean todos: ITodo[] todos_changed: number - reload_fromServer: boolean + reload_fromServer: number testpao: String insidePending: boolean } diff --git a/src/model/UserStore.ts b/src/model/UserStore.ts index 94c7c12..3e483e8 100644 --- a/src/model/UserStore.ts +++ b/src/model/UserStore.ts @@ -17,8 +17,6 @@ export interface IUserState { lang?: string repeatPassword?: string - idToken?: string - tokens?: IToken[] verified_email?: boolean @@ -27,6 +25,7 @@ export interface IUserState { tokenforgot?: string servercode?: number + resStatus?: number x_auth_token?: string isLogged?: boolean } diff --git a/src/model/other.ts b/src/model/other.ts index e40635d..6086868 100644 --- a/src/model/other.ts +++ b/src/model/other.ts @@ -1,6 +1,8 @@ export interface IToken { access: string + // browser: string token: string + data_login: Date } @@ -9,7 +11,7 @@ export interface ILinkReg { } export interface IIdToken { - idToken: string + x_auth_token: string } export interface IResult { diff --git a/src/root/home/home.ts b/src/root/home/home.ts index 30ac694..8f62da5 100644 --- a/src/root/home/home.ts +++ b/src/root/home/home.ts @@ -57,9 +57,10 @@ export default class Home extends Vue { initprompt() { window.addEventListener('beforeinstallprompt', function (event) { - console.log('******************************** beforeinstallprompt fired') + // console.log('******************************** beforeinstallprompt fired') event.preventDefault() - console.log('§§§§§§§§§§§§§§§§§§§§ IMPOSTA DEFERRED PROMPT !!!!!!!!!!!!!!!!! ') + // console.log('§§§§§§§§§§§§§§§§§§§§ IMPOSTA DEFERRED PROMPT !!!!!!!!!!!!!!!!! ') + // #Todo++ IMPOSTA DEFERRED PROMPT return false }) @@ -69,6 +70,10 @@ export default class Home extends Vue { return Notification.permission } + NotServiceWorker () { + return (!('serviceWorker' in navigator)) + } + displayConfirmNotification() { let options = null if ('serviceWorker' in navigator) { @@ -88,10 +93,12 @@ export default class Home extends Vue { ] } - navigator.serviceWorker.ready - .then(function (swreg) { - swreg.showNotification('Successfully subscribed!', options) - }) + if ('serviceWorker' in navigator) { + navigator.serviceWorker.ready + .then(function (swreg) { + swreg.showNotification('Successfully subscribed!', options) + }) + } } } @@ -168,7 +175,6 @@ export default class Home extends Vue { } - test_fetch() { fetch('https:/httpbin.org/post', { method: 'POST', diff --git a/src/root/home/home.vue b/src/root/home/home.vue index 1aa581b..7813d58 100644 --- a/src/root/home/home.vue +++ b/src/root/home/home.vue @@ -5,6 +5,8 @@ + +
@@ -16,6 +18,12 @@ :label="$t('notification.titlegranted')" helper="Stato Notifiche"> + +
diff --git a/src/router/route-config.ts b/src/router/route-config.ts index cdd182e..17cf55f 100644 --- a/src/router/route-config.ts +++ b/src/router/route-config.ts @@ -34,6 +34,11 @@ export const RouteConfig: VueRouteConfig[] = [ path: '/category', component: () => import('@/components/categories/category/category.vue'), meta: { name: 'Categories' } + }, + { + path: '/offline', + component: () => import('@/components/offline/offline.vue'), + meta: { name: 'Offline' } } /* { diff --git a/src/statics/i18n.js b/src/statics/i18n.js index 129ff64..e10e65c 100644 --- a/src/statics/i18n.js +++ b/src/statics/i18n.js @@ -17,7 +17,7 @@ const messages = { msg: { hello: 'Buongiorno', myAppName: 'FreePlanet', - myDescriz: 'La prima App Libera' + myDescriz: '' }, pages: { home: 'Principale', @@ -51,6 +51,7 @@ const messages = { fetch: { errore_generico: 'Errore Generico', errore_server: 'Impossibile accedere al Server. Riprovare Grazie', + error_doppiologin: 'Rieseguire il Login. Accesso aperto da un altro dispositivo.', }, user: { notregistered: 'Devi registrarti al servizio prima di porter memorizzare i dati' @@ -121,7 +122,8 @@ const messages = { titledenied: 'Permesso Notifiche Disabilitato!', title_subscribed: 'Sottoscrizione a FreePlanet.app!', subscribed: 'Ora potrai ricevere i messaggi e le notifiche.' - } + }, + connection: 'Connessione', }, es: { dialog: { @@ -141,7 +143,7 @@ const messages = { msg: { hello: 'Buenos Días', myAppName: 'FreePlanet', - myDescriz: 'La primera App Libera' + myDescriz: '' }, pages: { home: 'Principal', @@ -175,6 +177,7 @@ const messages = { fetch: { errore_generico: 'Error genérico', errore_server: 'No se puede acceder al Servidor. Inténtalo de nuevo, Gracias', + error_doppiologin: 'Vuelva a iniciar sesión. Acceso abierto por otro dispositivo.', }, user: { notregistered: 'Debe registrarse en el servicio antes de poder almacenar los datos' @@ -245,7 +248,8 @@ const messages = { titledenied: 'Notificaciones permitidas deshabilitadas!', title_subscribed: 'Suscripción a FreePlanet.app!', subscribed: 'Ahora puedes recibir mensajes y notificaciones.' - } + }, + connection: 'Connection', }, enUk: { dialog: { @@ -265,7 +269,7 @@ const messages = { msg: { hello: 'Hello!', myAppName: 'FreePlanet', - myDescriz: 'The first Free app' + myDescriz: '' }, pages: { home: 'Dashboard One', @@ -299,6 +303,7 @@ const messages = { fetch: { errore_generico: 'Generic Error', errore_server: 'Unable to access to the Server. Retry. Thank you.', + error_doppiologin: 'Signup again. Another access was made with another device.', }, user: { notregistered: 'You need first to SignUp before storing data' @@ -369,7 +374,8 @@ const messages = { titledenied: 'Notification Permission Denied!', title_subscribed: 'Subscribed to FreePlanet.app!', subscribed: 'You can now receive Notification and Messages.' - } + }, + connection: 'Conexión', }, }; diff --git a/src/statics/js/storage.js b/src/statics/js/storage.js index c8b2316..88d097f 100644 --- a/src/statics/js/storage.js +++ b/src/statics/js/storage.js @@ -1,5 +1,6 @@ let idbKeyval = (() => { let db; + // console.log('idbKeyval...') function getDB() { if (!db) { @@ -47,14 +48,28 @@ let idbKeyval = (() => { }); return req.result; }, + + // jsonCopy(src) { + // return JSON.parse(JSON.stringify(src)); + // }, + + // contains(a, b) { + // // array matches + // if (Array.isArray(b)) { + // return b.some(x => a.indexOf(x) > -1); + // } + // // string match + // return a.indexOf(b) > -1; + // }, + async getdata(table, key) { let req; await withStore('readonly', table, store => { - console.log('store', store, 'key', key) + // console.log('store', store, 'key', key) req = store.get(key); }); - // console.log('RISFINALE!', req.result) + return req.result; }, async getalldata(table) { @@ -73,7 +88,7 @@ let idbKeyval = (() => { }, async setdata(table, value) { let req; - console.log('setdata', table, value) + // console.log('setdata', table, value) await withStore('readwrite', table, store => { req = store.put(value); @@ -91,6 +106,7 @@ let idbKeyval = (() => { }); }, async clearalldata(table) { + // console.log('clearalldata', table) return await withStore('readwrite', table, store => { store.clear(); }); diff --git a/src/store/Api/Inst-Pao.ts b/src/store/Api/Inst-Pao.ts index 83d049d..871d025 100644 --- a/src/store/Api/Inst-Pao.ts +++ b/src/store/Api/Inst-Pao.ts @@ -7,7 +7,10 @@ async function sendRequest(url: string, lang: string, mytok: string, method: str const authHeader = new Headers() authHeader.append('content-Type', 'application/json') authHeader.append('Accept', 'application/json') - authHeader.append('x-auth', mytok) + if (url !== process.env.MONGODB_HOST + '/users/login') { + authHeader.append('x-auth', mytok) + // console.log('TOK PASSATO ALLA FETCH:', mytok) + } // authHeader.append('accept-language', lang) let configInit: RequestInit @@ -16,21 +19,27 @@ async function sendRequest(url: string, lang: string, mytok: string, method: str configInit = { method: method, cache: 'no-cache', + mode: 'cors', headers: authHeader } } else if (method === 'DELETE') { configInit = { method: method, cache: 'no-cache', + mode: 'cors', headers: authHeader } } else { configInit = { method: method, cache: 'no-cache', - body: JSON.stringify(mydata), + mode: 'cors', headers: authHeader } + + if (mydata !== null) + configInit.body = JSON.stringify(mydata) + } const request: Promise = fetch(url, configInit) diff --git a/src/store/Api/index.ts b/src/store/Api/index.ts index d8bec7f..0274374 100644 --- a/src/store/Api/index.ts +++ b/src/store/Api/index.ts @@ -9,8 +9,10 @@ export { addAuthHeaders, removeAuthHeaders, API_URL } from './Instance' import Paths from '@paths' import { rescodes } from '@src/store/Modules/rescodes' -import { UserStore } from '@modules' +import { GlobalStore, UserStore } from '@modules' import globalroutines from './../../globalroutines/index' +import { serv_constants } from '@src/store/Modules/serv_constants' +import router from '@router' // const algoliaApi = new AlgoliaSearch() @@ -45,53 +47,70 @@ export namespace ApiTool { }) } - export async function SendReq(url: string, lang: string, mytok: string, method: string, mydata: any, noAuth: boolean = false) { + export async function SendReq(url: string, method: string, mydata: any, setAuthToken: boolean = false) { UserStore.mutations.setServerCode(rescodes.EMPTY) - UserStore.mutations.setAuth('') + UserStore.mutations.setResStatus(0) return await new Promise(function (resolve, reject) { let ricevuto = false - sendRequest(url, lang, mytok, method, mydata) + + return sendRequest(url, UserStore.state.lang, UserStore.state.x_auth_token, method, mydata) .then(resreceived => { + console.log('resreceived', resreceived) ricevuto = true let res = resreceived.clone() if (process.env.DEV) { - console.log('SendReq RES [', res.status, ']', res) + // console.log('SendReq RES [', res.status, ']', res) } - let x_auth_token = '' + UserStore.mutations.setResStatus(res.status) if (res.status === 200) { + let x_auth_token = '' try { - if (!noAuth) { + if (setAuthToken) { x_auth_token = String(res.headers.get('x-auth')) - if (url === process.env.MONGODB_HOST + '/updatepwd') { - UserStore.mutations.UpdatePwd({ idToken: x_auth_token }) - localStorage.setItem(rescodes.localStorage.token, x_auth_token) - } - if (x_auth_token === '') { UserStore.mutations.setServerCode(rescodes.ERR_AUTHENTICATION) } + UserStore.mutations.setAuth(x_auth_token) + + if (url === process.env.MONGODB_HOST + '/updatepwd') { + UserStore.mutations.UpdatePwd({ x_auth_token }) + localStorage.setItem(rescodes.localStorage.token, x_auth_token) + } } UserStore.mutations.setServerCode(rescodes.OK) - UserStore.mutations.setAuth(x_auth_token) } catch (e) { - if (!noAuth) { + if (setAuthToken) { UserStore.mutations.setServerCode(rescodes.ERR_AUTHENTICATION) - UserStore.mutations.setAuth(x_auth_token) + UserStore.mutations.setAuth('') } - return reject(e) + GlobalStore.mutations.setStateConnection(ricevuto ? 'online' : 'offline') + return reject({ code: rescodes.ERR_AUTHENTICATION }) } + } else if (res.status === serv_constants.RIS_CODE__HTTP_FORBIDDEN_INVALID_TOKEN) { + // Forbidden + // You probably is connectiong with other page... + UserStore.mutations.setServerCode(rescodes.ERR_AUTHENTICATION) + UserStore.mutations.setAuth('') + GlobalStore.mutations.setStateConnection(ricevuto ? 'online' : 'offline') + router.push('/signin') + return reject({ code: rescodes.ERR_AUTHENTICATION }) } + GlobalStore.mutations.setStateConnection(ricevuto ? 'online' : 'offline') + return res.json() .then((body) => { - return resolve({ res, body }) + // console.log('BODY RES = ', body) + return resolve({ res, body, status: res.status }) }) .catch(e => { - UserStore.mutations.setServerCode(rescodes.ERR_GENERICO) - return reject(e) + return resolve({ res, body: {}, status: res.status }) + // Array not found... + // UserStore.mutations.setServerCode(rescodes.ERR_GENERICO) + // return reject({ code: rescodes.ERR_GENERICO, status: res.status }) }) }) @@ -104,7 +123,10 @@ export namespace ApiTool { } else { UserStore.mutations.setServerCode(rescodes.ERR_GENERICO) } - return reject(error) + + GlobalStore.mutations.setStateConnection(ricevuto ? 'online' : 'offline') + + return reject({ code: error }) }) }) } @@ -122,57 +144,74 @@ export namespace ApiTool { // let lang = multiparams[3] if (cmd === 'sync-todos') { - console.log('[Alternative] Syncing', cmd, table, method) + // console.log('[Alternative] Syncing', cmd, table, method) const headers = new Headers() headers.append('content-Type', 'application/json') headers.append('Accept', 'application/json') headers.append('x-auth', token) - console.log('A1) INIZIO.............................................................') + let errorfromserver = false + let lettoqualcosa = false - await globalroutines(null, 'readall', table, null) + // console.log('A1) INIZIO.............................................................') + return globalroutines(null, 'readall', table, null) .then(function (alldata) { const myrecs = [...alldata] - console.log('----------------------- LEGGO QUALCOSA ') - if (myrecs) { - for (let rec of myrecs) { - // console.log('syncing', table, '', rec.descr) - let link = process.env.MONGODB_HOST + '/todos' + // console.log('----------------------- LEGGO QUALCOSA ') - if (method !== 'POST') - link += '/' + rec._id + const promises = myrecs.map(rec => { + // console.log('syncing', table, '', rec.descr) + let link = process.env.MONGODB_HOST + '/todos' - console.log(' [Alternative] ++++++++++++++++++ SYNCING !!!! ', rec.descr, table, 'FETCH: ', method, link, 'data:') + if (method !== 'POST') + link += '/' + rec._id - // Insert/Delete/Update table to the server - fetch(link, { - method: method, - headers: headers, - mode: 'cors', // 'no-cors', - body: JSON.stringify(rec) + // console.log(' [Alternative] ++++++++++++++++++ SYNCING !!!! ', rec.descr, table, 'FETCH: ', method, link, 'data:') + + // Insert/Delete/Update table to the server + return fetch(link, { + method: method, + headers: headers, + cache: 'no-cache', + mode: 'cors', // 'no-cors', + body: JSON.stringify(rec) + }) + .then(() => { + lettoqualcosa = true + return globalroutines(null, 'delete', table, null, rec._id) }) - .then(function (resData) { - // console.log('Result CALL ', method, ' OK? =', resData.ok); + .then(() => { + return globalroutines(null, 'delete', 'swmsg', null, mystrparam) + }) + .catch(function (err) { + if (err.message === 'Failed to fetch') { + errorfromserver = true + } + // console.log(' [Alternative] !!!!!!!!!!!!!!! Error while sending data', err, errorfromserver, 'lettoqualcosa', lettoqualcosa) + }) + }) - // Anyway Delete this, otherwise in some cases will return error, but it's not a problem. - // for example if I change a record and then I deleted ... - // if (resData.ok) { - // deleteItemFromData(table, rec._id); - globalroutines(null, 'delete', table, null, rec._id) + // CALL ALL THE PROMISES + return Promise.all(promises).then(() => { + return (errorfromserver && !lettoqualcosa) + }).catch(err => { + return (errorfromserver && !lettoqualcosa) + }) - console.log('DELETE: ', mystrparam) - // deleteItemFromData('swmsg', mystrparam) - globalroutines(null, 'delete', 'swmsg', null, mystrparam) - - }) - .catch(function (err) { - console.log(' [Alternative] !!!!!!!!!!!!!!! Error while sending data', err) - }) - } - } + }).catch(e => { + // console.log('ERROR:', e) + return (errorfromserver && !lettoqualcosa) }) - console.log(' [Alternative] A2) ?????????????????????????? ESCO DAL LOOP !!!!!!!!! err=') + .then((errorfromserver) => { + // console.log('¨¨¨¨¨¨¨¨¨¨¨¨¨¨ errorfromserver:', errorfromserver) + const mystate = errorfromserver ? 'offline' : 'online' + GlobalStore.mutations.setStateConnection(mystate) + return globalroutines(null, 'write', 'config', { _id: 2, stateconn: mystate }) + }) + + // console.log(' [Alternative] A2) ?????????????????????????? ESCO DAL LOOP !!!!!!!!!') + } } } diff --git a/src/store/Modules/GlobalStore.ts b/src/store/Modules/GlobalStore.ts index ae71f84..0ebe182 100644 --- a/src/store/Modules/GlobalStore.ts +++ b/src/store/Modules/GlobalStore.ts @@ -1,4 +1,4 @@ -import { IGlobalState } from 'model' +import { IGlobalState, StateConnection } from 'model' import { storeBuilder } from './Store/Store' import Vue from 'vue' @@ -8,25 +8,50 @@ import translate from './../../globalroutines/util' import urlBase64ToUint8Array from '../../js/utility' import messages from '../../statics/i18n' -import { UserStore } from "@store" +import { GlobalStore, UserStore } from '@store' +import globalroutines from './../../globalroutines/index' +import Api from "@api" +import { rescodes } from "@src/store/Modules/rescodes" + +const allTables = ['todos', 'sync_todos', 'sync_todos_patch', 'delete_todos', 'config', 'swmsg'] +const allTablesAfterLogin = ['todos', 'sync_todos', 'sync_todos_patch', 'delete_todos', 'config', 'swmsg'] + +async function getstateConnSaved() { + const config = await globalroutines(null, 'readall', 'config', null) + if (config.length > 1) { + return config[1].stateconn + } else { + return 'online' + } +} + +let stateConnDefault = 'online' + +getstateConnSaved() + .then(conn => { + stateConnDefault = conn + }) const state: IGlobalState = { conta: 0, - isSubscribed: false, + wasAlreadySubscribed: false, + wasAlreadySubOnDb: false, isLoginPage: false, layoutNeeded: true, mobileMode: false, menuCollapse: true, leftDrawerOpen: true, + stateConnection: stateConnDefault, category: 'personal', posts: [], listatodo: [ - {namecat: 'personal', description: 'personal'}, - {namecat: 'work', description: 'work'}, - {namecat: 'shopping', description: 'shopping'} - ] + { namecat: 'personal', description: 'personal' }, + { namecat: 'work', description: 'work' }, + { namecat: 'shopping', description: 'shopping' } + ] } + const b = storeBuilder.module('GlobalModule', state) // Getters @@ -47,6 +72,10 @@ namespace Getters { get category() { return category() + }, + + get isOnline() { + return state.stateConnection === 'online' } } } @@ -65,11 +94,23 @@ namespace Mutations { state.category = cat } + function setStateConnection(state: IGlobalState, stateconn: StateConnection) { + if (state.stateConnection !== stateconn) { + console.log('INTERNET ', stateconn) + state.stateConnection = stateconn + } + } + + function SetwasAlreadySubOnDb(state: IGlobalState, subscrib: boolean) { + state.wasAlreadySubOnDb = subscrib + } export const mutations = { setConta: b.commit(setConta), setleftDrawerOpen: b.commit(setleftDrawerOpen), - setCategorySel: b.commit(setCategorySel) + setCategorySel: b.commit(setCategorySel), + setStateConnection: b.commit(setStateConnection), + SetwasAlreadySubOnDb: b.commit(SetwasAlreadySubOnDb) } } @@ -80,27 +121,41 @@ namespace Actions { } function createPushSubscription(context) { + + // If Already subscribed, don't send to the Server DB + // if (state.wasAlreadySubOnDb) { + // // console.log('wasAlreadySubOnDb!') + // return + // } + if (!('serviceWorker' in navigator)) { return } + if (!('PushManager' in window)) { + return + } + console.log('createPushSubscription') let reg const mykey = process.env.PUBLICKEY_PUSH const mystate = state - navigator.serviceWorker.ready + return navigator.serviceWorker.ready .then(function (swreg) { reg = swreg return swreg.pushManager.getSubscription() }) .then(function (subscription) { - mystate.isSubscribed = !(subscription === null) + mystate.wasAlreadySubscribed = !(subscription === null) - if (mystate.isSubscribed) { - console.log('User is already Subscribed!') + if (mystate.wasAlreadySubscribed) { + console.log('User is already SAVED Subscribe on DB!') + // return null + return subscription } else { // Create a new subscription + console.log('Create a new subscription') let convertedVapidPublicKey = urlBase64ToUint8Array(mykey) return reg.pushManager.subscribe({ userVisibleOnly: true, @@ -109,44 +164,66 @@ namespace Actions { } }) .then(function (newSub) { - if (newSub) { - saveNewSubscriptionToServer(context, newSub) - mystate.isSubscribed = true; - } - return null + saveNewSubscriptionToServer(context, newSub) }) .catch(function (err) { - console.log(err) + console.log('ERR createPushSubscription:', err) }) } // Calling the Server to Save in the MongoDB the Subscriber function saveNewSubscriptionToServer(context, newSub) { + // If already subscribed, exit + if (!newSub) + return + console.log('saveSubscriptionToServer: ', newSub) - console.log('context', context) + // console.log('context', context) - const options = { - title: translate('notification.title_subscribed'), - content: translate('notification.subscribed'), - openUrl: '/' - } + let options = null - let myres = { - options: { ...options }, - subs: newSub, - others: { - userId: UserStore.state.userId + // If is not already stored in DB, then show the message to the user. + if (!state.wasAlreadySubscribed) { + options = { + title: translate('notification.title_subscribed'), + content: translate('notification.subscribed'), + openUrl: '/' } } - return fetch(process.env.MONGODB_HOST + '/subscribe', { - method: 'POST', + let myres = { + options, + subs: newSub, + others: { + userId: UserStore.state.userId, + access: UserStore.state.tokens[0].access + }, + } + + let call = process.env.MONGODB_HOST + '/subscribe' + + return Api.SendReq(call, 'POST', myres) + .then(({ res, body }) => { + state.wasAlreadySubscribed = true + state.wasAlreadySubOnDb = true + + localStorage.setItem(rescodes.localStorage.wasAlreadySubOnDb, String(state.wasAlreadySubOnDb)) + }) + .catch(e => { + console.log('Error during Subscription!', e) + }) + } + + async function deleteSubscriptionToServer(context) { + console.log('DeleteSubscriptionToServer: ') + + return await fetch(process.env.MONGODB_HOST + '/subscribe/del', { + method: 'DELETE', headers: { 'Content-Type': 'application/json', - 'Accept': 'application/json' - }, - body: JSON.stringify(myres) - + 'Accept': 'application/json', + 'x-auth': UserStore.state.x_auth_token + } }) } @@ -174,8 +251,50 @@ namespace Actions { } - function loadAfterLogin (context) { + async function clearDataAfterLogout(context) { + console.log('clearDataAfterLogout') + // Clear all data from the IndexedDB + await allTables.forEach(table => { + globalroutines(null, 'clearalldata', table, null) + }) + + if ('serviceWorker' in navigator) { + // REMOVE ALL SUBSCRIPTION + console.log('REMOVE ALL SUBSCRIPTION...') + await navigator.serviceWorker.ready.then(function (reg) { + console.log('... Ready') + reg.pushManager.getSubscription().then(function (subscription) { + console.log(' Found Subscription...') + subscription.unsubscribe().then(function (successful) { + // You've successfully unsubscribed + console.log('You\'ve successfully unsubscribed') + }).catch(function (e) { + // Unsubscription failed + }) + }) + }) + } + + await deleteSubscriptionToServer(context) + + } + + async function clearDataAfterLoginOnlyIfActiveConnection(context) { + + // if (Getters.getters.isOnline) { + // console.log('clearDataAfterLoginOnlyIfActiveConnection') + // // Clear all data from the IndexedDB + // allTablesAfterLogin.forEach(table => { + // globalroutines(null, 'clearalldata', table, null) + // }) + // } + + } + + + async function loadAfterLogin(context) { + actions.clearDataAfterLoginOnlyIfActiveConnection() } @@ -183,6 +302,8 @@ namespace Actions { setConta: b.dispatch(setConta), createPushSubscription: b.dispatch(createPushSubscription), loadAfterLogin: b.dispatch(loadAfterLogin), + clearDataAfterLogout: b.dispatch(clearDataAfterLogout), + clearDataAfterLoginOnlyIfActiveConnection: b.dispatch(clearDataAfterLoginOnlyIfActiveConnection), prova: b.dispatch(prova) } @@ -202,4 +323,3 @@ const GlobalModule = { export default GlobalModule - diff --git a/src/store/Modules/Todos.ts b/src/store/Modules/Todos.ts index 55ac0ee..7c26958 100644 --- a/src/store/Modules/Todos.ts +++ b/src/store/Modules/Todos.ts @@ -5,7 +5,8 @@ import Api from '@api' import { rescodes } from './rescodes' import { GlobalStore, Todos, UserStore } from '@store' import globalroutines from './../../globalroutines/index' -import { Mutation } from "vuex-module-decorators" +import { Mutation } from 'vuex-module-decorators' +import { serv_constants } from '@src/store/Modules/serv_constants' const state: ITodosState = { @@ -13,7 +14,7 @@ const state: ITodosState = { networkDataReceived: false, todos: [], todos_changed: 1, - reload_fromServer: false, + reload_fromServer: 0, testpao: 'Test', insidePending: false } @@ -42,7 +43,7 @@ namespace Mutations { function setTodos_changed(state: ITodosState) { state.todos_changed++ mutations.setTestpao('Cambiato : ' + String(state.todos_changed)) - console.log('******************************* state.todos_changed', state.todos_changed) + // console.log('******* state.todos_changed', state.todos_changed) } export const mutations = { @@ -77,27 +78,27 @@ namespace Actions { let count = await checkPendingMsg(null) if (count > 0) { - return navigator.serviceWorker.ready + return await navigator.serviceWorker.ready .then(function (sw) { - globalroutines(null, 'readall', 'swmsg') + return globalroutines(null, 'readall', 'swmsg') .then(function (arr_recmsg) { // let recclone = [...arr_recmsg] if (arr_recmsg.length > 0) { - console.log(' TROVATI MSG PENDENTI ! ORA LI MANDO: ', arr_recmsg) + // console.log(' TROVATI MSG PENDENTI ! ORA LI MANDO: ', arr_recmsg) // console.log('---------------------- 2) navigator (2) .serviceWorker.ready') something = true for (let rec of arr_recmsg) { - console.log(' .... sw.sync.register ( ', rec._id) - if ('SyncManager' in window) { - sw.sync.register(rec._id) - } else { + // console.log(' .... sw.sync.register ( ', rec._id) + // if ('SyncManager' in window) { + // sw.sync.register(rec._id) + // } else { // #Todo ++ Alternative to SyncManager Api.syncAlternative(rec._id) - } + // } } return something } @@ -114,17 +115,15 @@ namespace Actions { await aspettansec(1000) - // console.log('waitAndcheckPendingMsg') - return await checkPendingMsg(context) .then(ris => { if (ris) { - console.log('ris = ', ris) - const result = sendSwMsgIfAvailable() + console.log('risPending = ', ris) + return sendSwMsgIfAvailable() .then(something => { if (something) { // Refresh data - waitAndRefreshData(context) + return waitAndRefreshData(context) } }) } @@ -135,14 +134,30 @@ namespace Actions { async function waitAndRefreshData(context) { await aspettansec(3000) - console.log('waitAndRefreshData') - return await dbLoadTodo(context, false) } async function checkPendingMsg(context) { // console.log('checkPendingMsg') + const config = await globalroutines(null, 'readall', 'config', null) + // console.log('config', config) + + try { + if (config) { + if (config[1].stateconn !== undefined) { + // console.log('config.stateconn', config[1].stateconn) + + if (config[1].stateconn !== GlobalStore.state.stateConnection) { + GlobalStore.mutations.setStateConnection(config[1].stateconn) + } + + } + } + } catch (e) { + + } + return new Promise(function (resolve, reject) { /* @@ -172,47 +187,56 @@ namespace Actions { async function dbLoadTodo(context, checkPending: boolean = false) { console.log('dbLoadTodo', checkPending) - const token = UserStore.state.idToken + if (UserStore.state.userId === '') + return false // Login not made let call = process.env.MONGODB_HOST + '/todos/' + UserStore.state.userId state.networkDataReceived = false - let ris = await Api.SendReq(call, UserStore.state.lang, token, 'GET', null) - .then(({ resData, body }) => { + let ris = await Api.SendReq(call, 'GET', null) + .then(({ res, body, status }) => { state.networkDataReceived = true - // console.log('******* UPDATE TODOS.STATE.TODOS !:', resData.todos) - state.todos = [...body.todos] - Todos.mutations.setTodos_changed() + // console.log('******* UPDATE TODOS.STATE.TODOS !:', res.todos) + if (body.todos) { + state.todos = [...body.todos] + // Todos.mutations.setTodos_changed() + } - console.log('state.todos', state.todos, 'checkPending', checkPending) + console.log('********** res', 'state.todos', state.todos, 'checkPending', checkPending) // After Login will store into the indexedDb... - return rescodes.OK + return { status } }) - .catch((error) => { + .catch(error => { + console.log('error=', error) UserStore.mutations.setErrorCatch(error) - return UserStore.getters.getServerCode + return { status } }) - console.log('fine della funz...') + // console.log('ris : ', ris) + // console.log('ris STATUS: ', ris.status) if (!Todos.state.networkDataReceived) { - console.log('NETWORK UNREACHABLE ! (Error in fetch)') - consolelogpao('NETWORK UNREACHABLE ! (Error in fetch)') + + if (ris.status === serv_constants.RIS_CODE__HTTP_FORBIDDEN_INVALID_TOKEN) { + consolelogpao('UNAUTHORIZING... TOKEN EXPIRED... !! ') + } else { + consolelogpao('NETWORK UNREACHABLE ! (Error in fetch)', UserStore.getters.getServerCode, ris.status) + } // Read all data from IndexedDB Store into Memory await updateArrayInMemory(context) } else { - if (ris === rescodes.OK && checkPending) { + if (ris.status === rescodes.OK && checkPending) { waitAndcheckPendingMsg(context) } } } async function updateArrayInMemory(context) { - console.log('Update the array in memory, from todos table from IndexedDb') + // console.log('Update the array in memory, from todos table from IndexedDb') await globalroutines(null, 'updateinMemory', 'todos', null) .then(() => { // console.log('updateArrayInMemory! ') @@ -246,8 +270,8 @@ namespace Actions { } function UpdateNewIdFromDB(oldItem, newItem, method) { - console.log('PRIMA state.todos', state.todos) - console.log('ITEM', newItem) + // console.log('PRIMA state.todos', state.todos) + // console.log('ITEM', newItem) if (method === 'POST') { state.todos.push(newItem) Todos.mutations.setTodos_changed() @@ -260,19 +284,22 @@ namespace Actions { } - console.log('DOPO state.todos', state.todos) + // console.log('DOPO state.todos', state.todos) } async function dbInsertSaveTodo(context, itemtodo: ITodo, method) { console.log('dbInsertSaveTodo', itemtodo, method) let call = process.env.MONGODB_HOST + '/todos' + if (UserStore.state.userId === '') + return false // Login not made + if (method !== 'POST') call += '/' + itemtodo._id - const token = UserStore.state.idToken + console.log('TODO TO SAVE: ', itemtodo) - let res = await Api.SendReq(call, UserStore.state.lang, token, method, itemtodo) + let res = await Api.SendReq(call, method, itemtodo) .then(({ res, newItem }) => { console.log('dbInsertSaveTodo RIS =', newItem) if (newItem) { @@ -290,12 +317,13 @@ namespace Actions { } async function dbDeleteTodo(context, item: ITodo) { - console.log('dbDeleteTodo', item) + // console.log('dbDeleteTodo', item) let call = process.env.MONGODB_HOST + '/todos/' + item._id - const token = UserStore.state.idToken + if (UserStore.state.userId === '') + return false // Login not made - let res = await Api.SendReq(call, UserStore.state.lang, token, 'DELETE', item) + let res = await Api.SendReq(call, 'DELETE', item) .then(function ({ res, itemris }) { if (res.status === 200) { diff --git a/src/store/Modules/UserStore.ts b/src/store/Modules/UserStore.ts index a9794c7..8930196 100644 --- a/src/store/Modules/UserStore.ts +++ b/src/store/Modules/UserStore.ts @@ -1,6 +1,6 @@ import Api from '@api' import { ISignupOptions, ISigninOptions, IUserState } from 'model' -import { ILinkReg, IResult, IIdToken } from 'model/other' +import { ILinkReg, IResult, IIdToken, IToken } from 'model/other' import { storeBuilder } from './Store/Store' import router from '@router' @@ -22,7 +22,6 @@ const state: IUserState = { password: '', lang: '', repeatPassword: '', - idToken: '', tokens: [], verified_email: false, categorySel: 'personal', @@ -44,17 +43,17 @@ namespace Getters { } }, 'lang') - const tok = b.read(state => { - if (state.tokens) { - if (typeof state.tokens[0] !== 'undefined') { - return state.tokens[0].token - } else { - return '' - } - } else { - return '' - } - }, 'tok') + // const tok = b.read(state => { + // if (state.tokens) { + // if (typeof state.tokens[0] !== 'undefined') { + // return state.tokens[0].token + // } else { + // return '' + // } + // } else { + // return '' + // } + // }, 'tok') const isServerError = b.read(state => { return (state.servercode === rescodes.ERR_SERVERFETCH) @@ -68,9 +67,9 @@ namespace Getters { get lang() { return lang() }, - get tok() { - return tok() - }, + // get tok() { + // return tok() + // }, get isServerError() { return isServerError() }, @@ -87,13 +86,11 @@ namespace Mutations { function authUser(state, data: IUserState) { state.userId = data.userId state.username = data.username - state.idToken = data.idToken state.verified_email = data.verified_email state.category = data.categorySel - // @ts-ignore - state.tokens = [ - { access: 'auth', token: data.idToken } - ] + resetArrToken(state.tokens) + state.tokens.push({ access: 'auth', token: state.x_auth_token, date_login: new Date() }) + // console.log('state.tokens', state.tokens) } function setpassword(state: IUserState, newstr: string) { @@ -110,26 +107,43 @@ namespace Mutations { } function UpdatePwd(state: IUserState, data: IIdToken) { - state.idToken = data.idToken + state.x_auth_token = data.x_auth_token if (!state.tokens) { state.tokens = [] } - state.tokens.push({ access: 'auth', token: data.idToken }) + state.tokens.push({ access: 'auth', token: data.x_auth_token, data_login: new Date() }) } function setServerCode(state: IUserState, num: number) { state.servercode = num } + function setResStatus(state: IUserState, status: number) { + state.resStatus = status + } + function setAuth(state: IUserState, x_auth_token: string) { + state.x_auth_token = x_auth_token } + + function resetArrToken(arrtokens) { + if (!arrtokens.tokens) { + arrtokens.tokens = [] + } + + // Take only the others access (from others Browser) + return arrtokens.filter((token: IToken) => { + return token.access !== 'auth' + }) + } + function clearAuthData(state: IUserState) { state.userId = '' state.username = '' - state.tokens = [] - state.idToken = '' + resetArrToken(state.tokens) + state.x_auth_token = '' state.verified_email = false state.categorySel = 'personal' } @@ -139,6 +153,7 @@ namespace Mutations { if (state.servercode !== rescodes.ERR_SERVERFETCH) { state.servercode = err } + console.log('Err catch: (servercode:', err, ')') } function getMsgError(state: IUserState, err: number) { @@ -168,6 +183,7 @@ namespace Mutations { setlang: b.commit(setlang), UpdatePwd: b.commit(UpdatePwd), setServerCode: b.commit(setServerCode), + setResStatus: b.commit(setResStatus), setAuth: b.commit(setAuth), clearAuthData: b.commit(clearAuthData), setErrorCatch: b.commit(setErrorCatch), @@ -205,13 +221,13 @@ namespace Actions { Mutations.mutations.setServerCode(rescodes.CALLING) - return await Api.SendReq(call, state.lang, Getters.getters.tok, 'POST', usertosend) + return await Api.SendReq(call, 'POST', usertosend, true) .then(({ res, body }) => { return { code: body.code, msg: body.msg } }) .catch((error) => { UserStore.mutations.setErrorCatch(error) - return UserStore.getters.getServerCode + return { code: UserStore.getters.getServerCode, msg: error } }) } @@ -230,7 +246,7 @@ namespace Actions { Mutations.mutations.setServerCode(rescodes.CALLING) - return await Api.SendReq(call, state.lang, Getters.getters.tok, 'POST', usertosend) + return await Api.SendReq(call, 'POST', usertosend) .then(({ res, body }) => { return { code: body.code, msg: body.msg } }).catch((error) => { @@ -253,13 +269,13 @@ namespace Actions { Mutations.mutations.setServerCode(rescodes.CALLING) - return await Api.SendReq(call, state.lang, Getters.getters.tok, 'POST', usertosend) + return await Api.SendReq(call, 'POST', usertosend) .then(({ res, body }) => { // console.log("RITORNO 2 "); // mutations.setServerCode(myres); if (body.code === serv_constants.RIS_CODE_EMAIL_VERIFIED) { console.log('VERIFICATO !!') - localStorage.setItem(rescodes.localStorage.verifiedEmail, '1') + localStorage.setItem(rescodes.localStorage.verified_email, String(true)) } else { console.log('Risultato di vreg: ', body.code) } @@ -296,16 +312,18 @@ namespace Actions { Mutations.mutations.setServerCode(rescodes.CALLING) - let x_auth_token: string = '' - - return Api.SendReq(call, state.lang, Getters.getters.tok, 'POST', usertosend) - .then(({ res, newuser }) => { + return Api.SendReq(call, 'POST', usertosend) + .then(({ res, body }) => { myres = res + const newuser = body + + console.log('newuser', newuser) + Mutations.mutations.setServerCode(myres.status) if (myres.status === 200) { - let userId = newuser.userId + let userId = newuser._id let username = authData.username if (process.env.DEV) { console.log('USERNAME = ' + username) @@ -313,9 +331,8 @@ namespace Actions { } Mutations.mutations.authUser({ - userId: userId, - username: username, - idToken: x_auth_token, + userId, + username, verified_email: false }) @@ -324,9 +341,9 @@ namespace Actions { const expirationDate = new Date(now.getTime() * 1000) localStorage.setItem(rescodes.localStorage.userId, userId) localStorage.setItem(rescodes.localStorage.username, username) - localStorage.setItem(rescodes.localStorage.token, x_auth_token) + localStorage.setItem(rescodes.localStorage.token, state.x_auth_token) localStorage.setItem(rescodes.localStorage.expirationDate, expirationDate.toString()) - localStorage.setItem(rescodes.localStorage.verifiedEmail, '0') + localStorage.setItem(rescodes.localStorage.verified_email, String(false)) state.isLogged = true // dispatch('storeUser', authData); // dispatch('setLogoutTimer', myres.data.expiresIn); @@ -349,71 +366,114 @@ namespace Actions { console.log('MYLANG = ' + state.lang) + let sub = null + + if ('serviceWorker' in navigator) { + sub = await navigator.serviceWorker.ready + .then(function (swreg) { + const sub = swreg.pushManager.getSubscription() + return sub + }) + .catch(e => { + sub = null + }) + } + + const options = { + title: translate('notification.title_subscribed'), + content: translate('notification.subscribed'), + openUrl: '/' + } + const usertosend = { username: authData.username, password: authData.password, idapp: process.env.APP_ID, keyappid: process.env.PAO_APP_ID, - lang: state.lang + lang: state.lang, + subs: sub, + options } console.log(usertosend) - let myres: IResult - Mutations.mutations.setServerCode(rescodes.CALLING) - return await Api.SendReq(call, state.lang, Getters.getters.tok, 'POST', usertosend) + let myres: IResult + + return Api.SendReq(call, 'POST', usertosend, true) .then(({ res, body }) => { myres = res - if (res.code === serv_constants.RIS_CODE_LOGIN_ERR) { + + if (body.code === serv_constants.RIS_CODE_LOGIN_ERR) { Mutations.mutations.setServerCode(body.code) - return body.code + return { myres, body } } Mutations.mutations.setServerCode(myres.status) + if (myres.status !== 200) { + return Promise.reject(rescodes.ERR_GENERICO) + } + return { myres, body } + + }).then(({ myres, body }) => { + + if (myres.status === serv_constants.RIS_CODE__HTTP_FORBIDDEN_INVALID_TOKEN) { + if (process.env.DEV) { + console.log('CODE = ' + body.code) + } + return body.code + } else if (myres.status !== 200) { + if (process.env.DEV) { + console.log('CODE = ' + body.code) + } + return body.code + } + if (myres.status === 200) { + GlobalStore.mutations.SetwasAlreadySubOnDb(body.subsExistonDb) + let myuser: IUserState = body.usertosend - let userId = myuser.userId - let username = authData.username - let verifiedEmail = myuser.verified_email === true - if (process.env.DEV) { - console.log('USERNAME = ' + username) - console.log('IDUSER= ' + userId) + if (myuser) { + let userId = myuser.userId + let username = authData.username + let verified_email = myuser.verified_email + if (process.env.DEV) { + console.log('USERNAME = ' + username, 'IDUSER= ' + userId) + // console.log('state.x_auth_token= ' + state.x_auth_token) + } + Mutations.mutations.authUser({ - userId: userId, - username: username, - idToken: state.x_auth_token, - verified_email: verifiedEmail + userId, + username, + verified_email }) + + const now = new Date() + // const expirationDate = new Date(now.getTime() + myres.data.expiresIn * 1000); + const expirationDate = new Date(now.getTime() * 1000) + localStorage.setItem(rescodes.localStorage.userId, userId) + localStorage.setItem(rescodes.localStorage.username, username) + localStorage.setItem(rescodes.localStorage.token, state.x_auth_token) + localStorage.setItem(rescodes.localStorage.expirationDate, expirationDate.toString()) + localStorage.setItem(rescodes.localStorage.isLogged, String(true)) + localStorage.setItem(rescodes.localStorage.verified_email, String(verified_email)) + localStorage.setItem(rescodes.localStorage.wasAlreadySubOnDb, String(GlobalStore.state.wasAlreadySubOnDb)) + } + } - const now = new Date() - // const expirationDate = new Date(now.getTime() + myres.data.expiresIn * 1000); - const expirationDate = new Date(now.getTime() * 1000) - localStorage.setItem(rescodes.localStorage.userId, userId) - localStorage.setItem(rescodes.localStorage.username, username) - localStorage.setItem(rescodes.localStorage.token, state.x_auth_token) - localStorage.setItem(rescodes.localStorage.expirationDate, expirationDate.toString()) - localStorage.setItem(rescodes.localStorage.isLogged, String(true)) - localStorage.setItem(rescodes.localStorage.verifiedEmail, Number(verifiedEmail).toString()) + return rescodes.OK - setGlobal() - - // dispatch('storeUser', authData); - // dispatch('setLogoutTimer', myres.data.expiresIn); - return rescodes.OK - } else if (myres.status === 404) { - if (process.env.DEV) { - console.log('CODE = ' + body.code) - } - return body.code + }).then(code => { + if (code === rescodes.OK) { + return setGlobal(true) + .then(() => { + return code + }) } else { - if (process.env.DEV) { - console.log('CODE = ' + body.code) - } - return body.code + return code } }) .catch((error) => { @@ -423,6 +483,20 @@ namespace Actions { } async function logout(context) { + console.log('logout') + + localStorage.removeItem(rescodes.localStorage.expirationDate) + localStorage.removeItem(rescodes.localStorage.token) + localStorage.removeItem(rescodes.localStorage.userId) + localStorage.removeItem(rescodes.localStorage.username) + localStorage.removeItem(rescodes.localStorage.isLogged) + // localStorage.removeItem(rescodes.localStorage.leftDrawerOpen) + localStorage.removeItem(rescodes.localStorage.verified_email) + localStorage.removeItem(rescodes.localStorage.categorySel) + localStorage.removeItem(rescodes.localStorage.wasAlreadySubOnDb) + + + await GlobalStore.actions.clearDataAfterLogout() let call = process.env.MONGODB_HOST + '/users/me/token' console.log('CALL ' + call) @@ -433,7 +507,7 @@ namespace Actions { } console.log(usertosend) - return await Api.SendReq(call, state.lang, Getters.getters.tok, 'DELETE', usertosend) + const riscall = await Api.SendReq(call, 'DELETE', usertosend) .then(({ res, body }) => { console.log(res) }).then(() => { @@ -443,37 +517,31 @@ namespace Actions { return UserStore.getters.getServerCode }) - localStorage.removeItem(rescodes.localStorage.expirationDate) - localStorage.removeItem(rescodes.localStorage.token) - localStorage.removeItem(rescodes.localStorage.userId) - localStorage.removeItem(rescodes.localStorage.username) - localStorage.removeItem(rescodes.localStorage.isLogged) - // localStorage.removeItem(rescodes.localStorage.leftDrawerOpen) - localStorage.removeItem(rescodes.localStorage.verifiedEmail) - localStorage.removeItem(rescodes.localStorage.categorySel) + return riscall - router.push('/signin') + // this.$router.push('/signin') } - function setGlobal() { + async function setGlobal(loggedWithNetwork: boolean) { state.isLogged = true GlobalStore.mutations.setleftDrawerOpen(localStorage.getItem(rescodes.localStorage.leftDrawerOpen) === 'true') GlobalStore.mutations.setCategorySel(localStorage.getItem(rescodes.localStorage.categorySel)) - GlobalStore.actions.loadAfterLogin() - - Todos.actions.dbLoadTodo(true) - + await GlobalStore.actions.loadAfterLogin() + .then(() => { + Todos.actions.dbLoadTodo(true) + }) } - async function autologin(context) { + async function autologin_FromLocalStorage(context) { try { - console.log('*** Autologin ***') + // console.log('*** autologin_FromLocalStorage ***') // INIT + UserStore.mutations.setlang(process.env.LANG_DEFAULT) - // ++Todo: Estrai la Lang dal Localstorage + // Estrai la Lang dal Localstorage const lang = localStorage.getItem('lang') if (lang) { UserStore.mutations.setlang(lang) @@ -492,18 +560,21 @@ namespace Actions { } const userId = String(localStorage.getItem(rescodes.localStorage.userId)) const username = String(localStorage.getItem(rescodes.localStorage.username)) - const verifiedEmail = localStorage.getItem(rescodes.localStorage.verifiedEmail) === '1' + const verified_email = localStorage.getItem(rescodes.localStorage.verified_email) === 'true' - console.log('autologin userId', userId) + GlobalStore.state.wasAlreadySubOnDb = localStorage.getItem(rescodes.localStorage.wasAlreadySubOnDb) === 'true' + + console.log('************* autologin userId', userId) + + UserStore.mutations.setAuth(token) Mutations.mutations.authUser({ userId: userId, username: username, - idToken: token, - verified_email: verifiedEmail + verified_email: verified_email, }) - setGlobal() + await setGlobal(false) console.log('autologin userId STATE ', state.userId) @@ -522,7 +593,7 @@ namespace Actions { signup: b.dispatch(signup), signin: b.dispatch(signin), logout: b.dispatch(logout), - autologin: b.dispatch(autologin) + autologin_FromLocalStorage: b.dispatch(autologin_FromLocalStorage) } } diff --git a/src/store/Modules/rescodes.ts b/src/store/Modules/rescodes.ts index 5a9f115..13ef138 100644 --- a/src/store/Modules/rescodes.ts +++ b/src/store/Modules/rescodes.ts @@ -12,7 +12,8 @@ export const rescodes = { LIST_START: '0', localStorage: { - verifiedEmail: 'vf', + verified_email: 'vf', + wasAlreadySubOnDb: 'sb', categorySel: 'cs', isLogged: 'ilog', expirationDate: 'expdate', diff --git a/src/store/Modules/serv_constants.ts b/src/store/Modules/serv_constants.ts index 0a8ab56..2b37d20 100644 --- a/src/store/Modules/serv_constants.ts +++ b/src/store/Modules/serv_constants.ts @@ -6,10 +6,11 @@ export const serv_constants = { RIS_CODE_EMAIL_VERIFIED: 1, RIS_CODE_LOGIN_ERR_GENERIC: -20, + RIS_CODE_LOGIN_ERR: -10, RIS_CODE_OK: 1, + RIS_CODE_LOGIN_OK: 1, - RIS_CODE_LOGIN_OK: 1 - + RIS_CODE__HTTP_FORBIDDEN_INVALID_TOKEN: 403 } diff --git a/src/views/login/requestresetpwd.vue b/src/views/login/requestresetpwd.vue index 14033e2..793e5f1 100644 --- a/src/views/login/requestresetpwd.vue +++ b/src/views/login/requestresetpwd.vue @@ -104,8 +104,8 @@ if (ris.code === serv_constants.RIS_CODE_OK) this.emailsent = true; this.$q.loading.hide(); - }).catch(error => { - console.log("ERROR = " + error); + }).catch(err => { + console.log("ERROR = " + err.error); this.$q.loading.hide(); }); diff --git a/src/views/login/signin/signin.ts b/src/views/login/signin/signin.ts index b89ea3d..c85632e 100644 --- a/src/views/login/signin/signin.ts +++ b/src/views/login/signin/signin.ts @@ -39,6 +39,11 @@ export default class Signin extends Vue { created() { this.$v.$reset() + + if (UserStore.state.resStatus === serv_constants.RIS_CODE__HTTP_FORBIDDEN_INVALID_TOKEN) { + this.showNotif(this.$t('fetch.error_doppiologin')) + } + // this.$myconfig.socialLogin.facebook = true // console.log('PROVA fb:', this.$myconfig.socialLogin.facebook) } @@ -75,8 +80,17 @@ export default class Signin extends Vue { this.showNotif({ type: 'positive', message: this.$t('login.completato') }) this.$router.push('/') } else if (riscode === serv_constants.RIS_CODE_LOGIN_ERR) { - this.showNotif(this.$t('login.errato')) - this.$router.push('/signin') + + // Wait N seconds to avoid calling many times... + return new Promise(function (resolve, reject) { + setTimeout(function () { + resolve('anything') + }, 1000) + }).then(() => { + this.showNotif(this.$t('login.errato')) + this.$router.push('/signin') + }) + } else if (riscode === rescodes.ERR_SERVERFETCH) { this.showNotif(this.$t('fetch.errore_server')) } else if (riscode === rescodes.ERR_GENERICO) { @@ -122,21 +136,35 @@ export default class Signin extends Vue { console.log(this.signin) UserStore.actions.signin(this.signin) .then((riscode) => { - console.log('riscode=', riscode) + // console.log('riscode=', riscode) if (riscode === rescodes.OK) { router.push('/signin') - globalroutines(this, 'loadapp', '') - - GlobalStore.actions.createPushSubscription() } - this.checkErrors(riscode) - this.$q.loading.hide() - }).catch(error => { - console.log('ERROR = ' + error) + return riscode + }).then((riscode) => { + globalroutines(this, 'loadapp', '') + return riscode + }) + .then((riscode) => { + if (riscode === rescodes.OK) { + GlobalStore.actions.createPushSubscription() + .then(ris => { + }) + .catch(e => { + console.log('ERROR = ' + e) + }) + .then(() => { + this.checkErrors(riscode) + this.$q.loading.hide() + }) + } + }) + .catch(error => { + console.log('ERROR = ' + error) - this.checkErrors(error) - this.$q.loading.hide() - }) + this.checkErrors(error) + this.$q.loading.hide() + }) } } diff --git a/src/views/login/vreg/vreg.ts b/src/views/login/vreg/vreg.ts index 6578ff1..ab836e8 100644 --- a/src/views/login/vreg/vreg.ts +++ b/src/views/login/vreg/vreg.ts @@ -8,9 +8,7 @@ import { serv_constants } from '../../../store/Modules/serv_constants' import './vreg.css' import { ILinkReg } from '../../../model/other' -@Component({ - -}) +@Component({}) export default class Vreg extends Vue { public risultato: string = '---' public riscode: number = 0 @@ -43,20 +41,21 @@ export default class Vreg extends Vue { let param: ILinkReg param = { idlink: this.$route.query.idlink.toString() } console.log('idlink = ', param) - UserStore.actions.vreg(param).then((ris) => { - this.riscode = ris.code - this.risultato = ris.msg - console.log('RIS = ') - console.log(ris) + return UserStore.actions.vreg(param) + .then((ris) => { + this.riscode = ris.code + this.risultato = ris.msg + console.log('RIS = ') + console.log(ris) - if (this.verificatook) { - setTimeout(() => { - this.$router.replace('/signin') - }, 3000) - } + if (this.verificatook) { + setTimeout(() => { + this.$router.replace('/signin') + }, 3000) + } - }).catch((err) => { - console.log('ERR = ' + err) + }).catch((err) => { + console.log('ERR = ' + err) }) } }