diff --git a/.example.env b/.example.env new file mode 100644 index 0000000..2b3af4d --- /dev/null +++ b/.example.env @@ -0,0 +1,11 @@ +NUXT_ENV_API_VAR=local + +NUXT_ENV_ENCRYPT_MODE=no + +NUXT_ENV_PORT_DEV=3000 +NUXT_ENV_PORT_PREPROD=8000 +NUXT_ENV_PORT_PROD=3000 + +NUXT_ENV_API_DEV=http://localhost:4000/api +NUXT_ENV_API_PREPROD=https://solidata-preprod-api.co-demos.com/api +NUXT_ENV_API_PROD=https://solidata-api.co-demos.com/api \ No newline at end of file diff --git a/.gitignore b/.gitignore index 16ae043..3edf4dd 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,8 @@ npm-debug.log # Nuxt generate dist +# env files +.env .DS_Store node_modules/ diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 0000000..1250fbd --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +v13.12.0 diff --git a/components/Footer/Footer.vue b/components/Footer/Footer.vue index f3277a4..cc408b1 100644 --- a/components/Footer/Footer.vue +++ b/components/Footer/Footer.vue @@ -279,6 +279,7 @@ export default { doc_id: this.$store.state.auth.user_id, form: [{ 'field_to_update': 'profile.agreement', + 'doc_type': 'usr', 'field_value': true }] } diff --git a/components/Forms/login.vue b/components/Forms/login.vue index a31b77d..e6e2862 100644 --- a/components/Forms/login.vue +++ b/components/Forms/login.vue @@ -228,22 +228,32 @@ export default { // - - - - - - - - - - - - - // // use saltToken as public_key for RSA encryption + const rsaEncrypt = this.$store.state.RSA_ENCRYPT + const antispamMode = this.$store.state.ANTISPAM_MODE var saltToken = this.$store.state.auth.salt_token // var TEST_PLUGIN = this.$EncryptionRSA( this.password, saltToken ) // console.log("> > > TEST_PLUGIN : ", TEST_PLUGIN ) ; - var encryptedPwd = this.$EncryptionRSA(this.password, saltToken) + var encryptedPwd = this.$EncryptionRSA(this.password, saltToken, rsaEncrypt) console.log('encryptedPwd : ', encryptedPwd) - var encryptedEmail = this.$EncryptionRSA(this.email_bis, saltToken) + var encryptedEmail = this.$EncryptionRSA(this.email_bis, saltToken, rsaEncrypt) console.log('encryptedEmail : ', encryptedEmail) - let pseudoForm = { - // email : this.email, - email_encrypt: encryptedEmail.hashed, - // pwd : this.password, - pwd_encrypt: encryptedPwd.hashed + let pseudoForm = {} + + if (rsaEncrypt) { + pseudoForm.email_encrypt = encryptedEmail.hashed + pseudoForm.pwd_encrypt = encryptedPwd.hashed + } else { + pseudoForm.email = encryptedEmail.hashed + pseudoForm.pwd = encryptedPwd.hashed + } + + // TO FINISH + if (antispamMode) { + console.log('submitLogin / antispamMode :', antispamMode) } // dispatch action from store/auth diff --git a/components/Forms/register.vue b/components/Forms/register.vue index 3d1d191..e809c97 100644 --- a/components/Forms/register.vue +++ b/components/Forms/register.vue @@ -202,20 +202,25 @@ export default { computed: { pseudoForm () { if (process.client === true) { + const rsaEncrypt = this.$store.state.RSA_ENCRYPT const saltToken = this.$store.state.auth.salt_token - var encryptedPwd = this.password !== '' ? this.$EncryptionRSA(this.password, saltToken) : '' - var encryptedEmail = this.email_bis !== '' ? this.$EncryptionRSA(this.email_bis, saltToken) : '' + var encryptedPwd = this.password !== '' ? this.$EncryptionRSA(this.password, saltToken, rsaEncrypt) : '' + var encryptedEmail = this.email_bis !== '' ? this.$EncryptionRSA(this.email_bis, saltToken, rsaEncrypt) : '' let pseudoForm = { - // email : this.email, - email_encrypt: encryptedEmail.hashed, - pwd_encrypt: encryptedPwd.hashed, name: this.name, surname: this.surname, - // pwd : this.password, lang: this.$store.state.locale, agreement: this.agreement } + if (rsaEncrypt) { + pseudoForm.email_encrypt = encryptedEmail.hashed + pseudoForm.pwd_encrypt = encryptedPwd.hashed + } else { + pseudoForm.email = encryptedEmail.hashed + pseudoForm.pwd = encryptedPwd.hashed + } + return pseudoForm } } diff --git a/components/UI/itemToolbar.vue b/components/UI/itemToolbar.vue index 1faeaa9..49edecc 100644 --- a/components/UI/itemToolbar.vue +++ b/components/UI/itemToolbar.vue @@ -193,12 +193,16 @@ + {{ $store.state.mainIcons.export.icon }} @@ -584,7 +588,7 @@ export default { return (this.isPreview) ? 'white' : 'primary' }, docAPIurl () { - return this.$store.state.APIURL + "/" + this.coll + "/documentation" + return this.$store.state.APIURL + '/' + this.coll + '/documentation' } }, @@ -635,6 +639,44 @@ export default { return canUpdateField }, + downloadDataset () { + this.$store.state.LOG && this.$store.state.LOG && console.log('itemToolbar - downloadDataset ...') + + this.loading = true + // this.is_loading = true + + let exportInput = { + coll: this.coll, + doc_id: this.itemId + } + this.$store.dispatch('downloadDataset', exportInput) + + .then(response => { + this.$store.state.LOG && console.log('itemToolbar - downloadDataset / response: ', response) + this.$store.state.LOG && console.log('itemToolbar - downloadDataset / response.data: ', response.data) + + this.loading = false + + let fileName = this.coll + '_' + this.itemTitle + '.csv' + + let blob = new Blob([response], {type: 'text/csv'}) + const link = document.createElement('a') + link.href = window.URL.createObjectURL(blob) + link.setAttribute('download', fileName) // or any other extension + document.body.appendChild(link) + link.click() + }) + + .catch(error => { + this.$store.state.LOG && console.log('itemToolbar - downloadDataset / error... : ', error) + this.loading = false + this.is_loading = false + if (error.response && error.response.data) { + this.alert = {type: 'error', message: error.response.data.msg || error.reponse.status} + } + }) + }, + reloadData () { this.$store.state.LOG && this.$store.state.LOG && console.log('itemToolbar - reloadData ...') const reloadSpecs = this.$store.state[this.coll].reload_data @@ -669,7 +711,7 @@ export default { this.$store.state.LOG && console.log('\n itemToolbar - deleItem ... ') this.loading = true - this.is_loading = true + // this.is_loading = true var callInput = { coll: this.coll, @@ -682,7 +724,7 @@ export default { this.$store.state.LOG && console.log('itemToolbar - deleItem / response: ', response) this.loading = false - this.is_loading = false + // this.is_loading = false this.alert = {type: 'success', message: response.msg} return this.$router.push(`/${this.coll}`) @@ -692,7 +734,7 @@ export default { this.$store.state.LOG && console.log('itemToolbar - deleItem / error... : ', error) this.loading = false - this.is_loading = false + // this.is_loading = false if (error.response && error.response.data) { this.alert = {type: 'error', message: error.response.data.msg || error.reponse.status} diff --git a/middleware/checkTokens.js b/middleware/checkTokens.js index bb1aae9..9d0e172 100644 --- a/middleware/checkTokens.js +++ b/middleware/checkTokens.js @@ -56,14 +56,6 @@ export default function ({ req, store, app, redirect }) { } catch (error) { console.log('- - - ... fucking error in parsing cookie with process.server == true : \n', error) } - // try { - // langCookie = parsed.lang; - // console.log("- - - checkTokens / langCookie :", langCookie) ; - // store.commit('SET_LANG', langCookie, { root: true }) ; - // } - // catch(error) { - // console.log("- - - ... fucking error in parsing cookie with process.server == true : \n", error) - // } } } @@ -125,9 +117,12 @@ export default function ({ req, store, app, redirect }) { // if ( accessToken == null || store.state.auth.isAnonymous ) { if (accessToken == null) { // if neither tokens in cookie nor store consider user as anonymous and get anonymous access_token + let promisesList = [] console.log('- - - checkTokens / no access_token detected') const accessAnonymous = store.dispatch('auth/loginAnonymous') - return Promise.all([ accessAnonymous ]) + promisesList.push(accessAnonymous) + // return Promise.all([ accessAnonymous ]) + return Promise.all(promisesList) } else { // 2b // If the user an access_token and a test them console.log('- - - checkTokens / access_token and refresh_token detected') diff --git a/nuxt.config.js b/nuxt.config.js index 164dad6..b6b6979 100644 --- a/nuxt.config.js +++ b/nuxt.config.js @@ -1,7 +1,27 @@ +import pkg from './package' +import { noConflict } from 'q' + +require('dotenv').config() + +console.log('\n>>> nuxt.config.js / process.env.NUXT_ENV_API_VAR : ', process.env.NUXT_ENV_API_VAR) +console.log('\n>>> nuxt.config.js / process.env.NUXT_ENV_RSA_ENCRYPT : ', process.env.NUXT_ENV_RSA_ENCRYPT) +console.log('\n>>> nuxt.config.js / process.env.NUXT_ENV_ANONYMOUS_MODE : ', process.env.NUXT_ENV_ANONYMOUS_MODE) +console.log('\n>>> nuxt.config.js / process.env.NUXT_ENV_ANTISPAM_MODE : ', process.env.NUXT_ENV_ANTISPAM_MODE) + +const trueStrings = ['yes', 'Yes', 'YES', 'y', 'Y', 'true', 'True', 'TRUE', 't', 'T'] +// const falseStrings = ['no', 'No', 'NO', 'n', 'N', 'false', 'False', 'FALSE', 'f', 'F'] + +const chooseBooleanMode = (ARG) => { + if (trueStrings.includes(ARG)) { + return true + } else { + return false + } +} const chooseAPIbaseUrl = (ENVPROD) => { - const NUXT_ENV_API_DEV = 'http://localhost:4000/api' - const NUXT_ENV_API_PREPROD = 'https://solidata-preprod-api.co-demos.com/api' - const NUXT_ENV_API_PROD = 'https://solidata-api.co-demos.com/api' + const NUXT_ENV_API_DEV = process.env.NUXT_ENV_API_DEV || 'http://localhost:4000/api' + const NUXT_ENV_API_PREPROD = process.env.NUXT_ENV_API_PREPROD || 'https://solidata-preprod-api.co-demos.com/api' + const NUXT_ENV_API_PROD = process.env.NUXT_ENV_API_PROD || 'https://solidata-api.co-demos.com/api' if (ENVPROD === 'local') { return NUXT_ENV_API_DEV } else if (ENVPROD === 'preprod') { @@ -11,9 +31,9 @@ const chooseAPIbaseUrl = (ENVPROD) => { } } const choosePort = (ENVPROD) => { - const NUXT_ENV_PORT_DEV = 3000 - const NUXT_ENV_PORT_PREPROD = 8000 - const NUXT_ENV_PORT_PROD = 3000 + const NUXT_ENV_PORT_DEV = parseInt(process.env.NUXT_ENV_PORT_DEV) || 3000 + const NUXT_ENV_PORT_PREPROD = parseInt(process.env.NUXT_ENV_PORT_PREPROD) || 8000 + const NUXT_ENV_PORT_PROD = parseInt(process.env.NUXT_ENV_PORT_PROD) || 3000 if (ENVPROD === 'local') { return NUXT_ENV_PORT_DEV } else if (ENVPROD === 'preprod') { @@ -25,11 +45,15 @@ const choosePort = (ENVPROD) => { const logAllowed = ['preprod', 'local'] const configApp = { API_URL: chooseAPIbaseUrl(process.env.NUXT_ENV_API_VAR), + ANO_MODE: chooseBooleanMode(process.env.NUXT_ENV_ANONYMOUS_MODE || 'yes'), + ANTISPAM_MODE: chooseBooleanMode(process.env.NUXT_ENV_ANTISPAM_MODE || 'no'), + RSA_ENCRYPT: chooseBooleanMode(process.env.NUXT_ENV_RSA_ENCRYPT || 'no'), port: choosePort(process.env.NUXT_ENV_API_VAR), mode: process.env.NUXT_ENV_API_VAR } -console.log('process.env :', process.env) -console.log('configApp :', configApp) +console.log('\nprocess.env :', process.env) +console.log('\nconfigApp :', configApp) + module.exports = { mode: 'universal', @@ -65,7 +89,7 @@ module.exports = { DEBUG: process.env.NODE_ENV === 'development', MODE_APP: configApp.mode, LOG: logAllowed.includes(configApp.mode), - CONFIG_APP: configApp, + CONFIG_APP: configApp }, router: { diff --git a/package-lock.json b/package-lock.json index fb80675..2be5e60 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3373,6 +3373,11 @@ "is-obj": "^1.0.0" } }, + "dotenv": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.0.0.tgz", + "integrity": "sha512-30xVGqjLjiUOArT4+M5q9sYdvuR4riM6yK9wMcas9Vbp6zZa+ocC9dp6QoftuhTPhFAiLK/0C5Ni2nou/Bk8lg==" + }, "dotprop": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/dotprop/-/dotprop-1.0.2.tgz", diff --git a/package.json b/package.json index 69d7ec0..bc8924a 100644 --- a/package.json +++ b/package.json @@ -5,17 +5,17 @@ "author": "JPy ", "private": true, "scripts": { - "dev": "NUXT_ENV_API_VAR=local nuxt", - "dev_preprod": "NUXT_ENV_API_VAR=preprod nuxt", - "build_dev": "NUXT_ENV_API_VAR=local nuxt build", - "start_dev": "NUXT_ENV_API_VAR=local nuxt start", - "generate_dev": " NUXT_ENV_API_VAR=local nuxt generate", - "build_preprod": " NUXT_ENV_API_VAR=preprod nuxt build", - "start_preprod": " NUXT_ENV_API_VAR=preprod nuxt start", - "generate_preprod": " NUXT_ENV_API_VAR=preprod nuxt generate", - "build": " NUXT_ENV_API_VAR=prod nuxt build", - "start": " NUXT_ENV_API_VAR=prod nuxt start", - "generate": " NUXT_ENV_API_VAR=prod nuxt generate" + "dev": "nuxt", + "dev_preprod": "nuxt", + "build_dev": "nuxt build", + "start_dev": "nuxt start", + "generate_dev": "nuxt generate", + "build_preprod": "nuxt build", + "start_preprod": "nuxt start", + "generate_preprod": "nuxt generate", + "build": "nuxt build", + "start": "nuxt start", + "generate": "nuxt generate" }, "dependencies": { "@fortawesome/fontawesome-svg-core": "^1.2.2", @@ -31,6 +31,7 @@ "cookie": "^0.3.1", "cookieparser": "^0.1.0", "crypto-js": "^3.1.9-1", + "dotenv": "^8.0.0", "epic-spinners": "^1.0.3", "i": "^0.3.6", "js-cookie": "^2.2.0", diff --git a/plugins/encrypt.js b/plugins/encrypt.js index 566e2d1..e1b8801 100644 --- a/plugins/encrypt.js +++ b/plugins/encrypt.js @@ -5,27 +5,28 @@ import JSEncrypt from 'jsencrypt' console.log('> > > plugins/encrypt... ') -Vue.prototype.$EncryptionRSA = (stringToEncrypt, publicKey) => { +Vue.prototype.$EncryptionRSA = (stringToEncrypt, publicKey, rsaEncrypt = true) => { // cf : https://github.com/travist/jsencrypt - // console.log('> > > plugin EncryptionRSA / stringToEncrypt : ', stringToEncrypt) + console.log('> > > plugin EncryptionRSA / stringToEncrypt : ', stringToEncrypt) // console.log('> > > plugin EncryptionRSA / publicKey : ', publicKey) - // NODE-RSA TEST - // const key = new NodeRSA(pem_public_key); - // // string to bytes - // var buffer = new Buffer(stringToEncrypt, "utf8") - // var encrypted = key.encrypt(buffer, "hex") + console.log('> > > plugin EncryptionRSA / process.env : ', process.env) + console.log('> > > plugin EncryptionRSA / rsaEncrypt : ', rsaEncrypt) - // JSENCRYPT - // Encrypt with the public key... - var encrypt = new JSEncrypt() - // console.log('> > > plugin EncryptString / encrypt : ', encrypt) - encrypt.setPublicKey(publicKey) - var encrypted = encrypt.encrypt(stringToEncrypt) + let encrypted - // console.log('> > > plugin EncryptString / encrypted : ', encrypted) + if (rsaEncrypt) { + // JSENCRYPT - Encrypt with the public key... + var encrypt = new JSEncrypt() + // console.log('> > > plugin EncryptString / encrypt : ', encrypt) + encrypt.setPublicKey(publicKey) + encrypted = encrypt.encrypt(stringToEncrypt) + } else { + encrypted = stringToEncrypt + } + // console.log('> > > plugin EncryptString / encrypted : ', encrypted) return { salt: publicKey, hashed: encrypted diff --git a/store/auth.js b/store/auth.js index 9073935..87843a2 100644 --- a/store/auth.js +++ b/store/auth.js @@ -220,35 +220,40 @@ export const actions = { loginAnonymous ({commit, dispatch, rootState}) { console.log('\n...store/auth : loginAnonymous...') - // var logout = dispatch('logout'); - - return this.$axios.$get('auth/login/anonymous/') - - .then(response => { - console.log('\n...store/auth/loginAnonymous : response : ', response) - commit('set_isAnonymous', true) - commit('set_isLogged', false) - commit('set_user', anonymousInfos) - commit('set_tokens', response.tokens) - - // cf documentation js-cookie : https://github.com/js-cookie/js-cookie - Cookie.set('access_token', response.tokens.access_token) - Cookie.set('refresh_token', response.tokens.refresh_token) - Cookie.set('salt_token', response.tokens.salt_token) - - // localStorage.removeItem("tokens"); - // resolve() - return response - }) - - .catch(error => { - return error - }) + let anonymousMode = rootState.ANO_MODE + console.log('...store/auth : loginAnonymous / anonymousMode :', anonymousMode) + + if (anonymousMode) { + return this.$axios.$get('auth/login/anonymous/') + + .then(response => { + console.log('...store/auth/loginAnonymous : response : ', response) + commit('set_isAnonymous', true) + commit('set_isLogged', false) + commit('set_user', anonymousInfos) + commit('set_tokens', response.tokens) + + // cf documentation js-cookie : https://github.com/js-cookie/js-cookie + Cookie.set('access_token', response.tokens.access_token) + Cookie.set('refresh_token', response.tokens.refresh_token) + Cookie.set('salt_token', response.tokens.salt_token) + + // localStorage.removeItem("tokens"); + // resolve() + return response + }) + + .catch(error => { + return error + }) + } else { + return true + } }, register ({commit, state}, data) { console.log('\n...store/auth : register...') - console.log('\n...store/auth/register : data : ', data) + console.log('...store/auth/register : data : ', data) // needs an anonymous access_token to create new user const config = {'headers': { 'Authorization': state.access_token }} diff --git a/store/index.js b/store/index.js index 19aec64..32f7441 100755 --- a/store/index.js +++ b/store/index.js @@ -228,6 +228,9 @@ export const state = () => ({ LOG: process.env.LOG, CONFIG: process.env.CONFIG_APP, APIURL: process.env.CONFIG_APP.API_URL, + RSA_ENCRYPT: process.env.CONFIG_APP.RSA_ENCRYPT, + ANO_MODE: process.env.CONFIG_APP.ANO_MODE, + ANTISPAM_MODE: process.env.CONFIG_APP.ANTISPAM_MODE, is_debug: false, // APP TITLE @@ -1034,6 +1037,35 @@ export const actions = { }) }, + downloadDataset ({commit, state, rootState}, input) { + state.LOG && console.log('\n... $ downloadDataset : input : ', input) + + var collection = input.coll + var docId = input.doc_id + + const config = { + headers: { + 'Authorization': rootState.auth.access_token, + 'Accept': 'application/octet-stream' + } + // responseType: 'blob', + // responseType: 'arraybuffer' + } + state.LOG && console.log('... $ downloadDataset : config : ', config) + + return this.$axios.$get(`${collection}/exports/as_csv/${docId}`, config) + .then(response => { + state.LOG && console.log(`... $ downloadDataset : response : `, response) + // commit(`set_alert`, response.msg) + return response + }) + .catch(error => { + state.LOG && console.log('... $ downloadDataset / error : ', error) + commit(`set_error`, error) + return error + }) + }, + deleteItem ({commit, state, rootState}, input) { state.LOG && console.log('\n... $ deleteItem : input : ', input)