Skip to content
This repository has been archived by the owner on May 28, 2023. It is now read-only.

Commit

Permalink
Merge pull request #133 from DivanteLtd/develop
Browse files Browse the repository at this point in the history
Release 1.5.0
  • Loading branch information
pkarw authored Oct 22, 2018
2 parents 7546d98 + 48c89b3 commit 92c96a6
Show file tree
Hide file tree
Showing 9 changed files with 859 additions and 1,114 deletions.
37 changes: 37 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,43 @@ NOTE: `npm` users will still have to install the dependencies individually in th
## Reviews
To use review feature you need to install custom module for Magento 2: [Divante ReviewApi](https://github.com/DivanteLtd/magento2-review-api)

## Running initial Magento2 import

Magento2 data import is now integrated into `vue-storefront-api` for simplicity. It's still managed by the [mage2vuestorefront](https://github.com/DivanteLtd/mage2vuestorefront) - added as a dependency to `vue-storefront-api`.

After setting the `config.magento2.api` section using Yours Magento2 oauth credentials:

```json
"magento2": {
"url": "http://magento2.demo-1.xyz.com",
"imgUrl": "http://localhost:8080/media/catalog/product",
"assetPath": "/../var/magento2-sample-data/pub/media",
"magentoUserName": "",
"magentoUserPassword": "",
"httpUserName": "",
"httpUserPassword": "",
"api": {
"url": "http://demo-magento2.vuestorefront.io/rest",
"consumerKey": "byv3730rhoulpopcq64don8ukb8lf2gq",
"consumerSecret": "u9q4fcobv7vfx9td80oupa6uhexc27rb",
"accessToken": "040xx3qy7s0j28o3q0exrfop579cy20m",
"accessTokenSecret": "7qunl3p505rubmr7u1ijt7odyialnih9"
}
},
```

You can run the following command to execute the full import:

```bash
yarn mage2vs import
```

... or in multistore setup You can run the same command with specified `store-code` parameter
`
``bash
yarn mage2vs import --store-code=de
```
License
-------
Expand Down
16 changes: 14 additions & 2 deletions config/default.json
Original file line number Diff line number Diff line change
Expand Up @@ -117,13 +117,25 @@
"registeredExtensions": [
"mailchimp-subscribe",
"example-magento-api",
"cms-data"
"cms-data",
"mail-service"
],
"extensions": {
"mailchimp": {
"listId": "e06875a7e1",
"apiKey": "a9a3318ea7d30f5c5596bd4a78ae0985-us3",
"apiUrl": "https://us3.api.mailchimp.com/3.0"
},
"mailService": {
"transport": {
"host": "smtp.gmail.com",
"port": 465,
"secure": true,
"user": "vuestorefront",
"pass": "vuestorefront.io"
},
"targetAddressWhitelist": ["[email protected]"],
"secretString": "__THIS_IS_SO_SECRET__"
}
},
"magento2": {
Expand Down Expand Up @@ -160,7 +172,7 @@
"concurrency": 0,
"counters": {
"queue": 2,
"process": 4
"process": 4
},
"simd": true,
"keepDownloads": true
Expand Down
6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
"start": "pm2 start ecosystem.json $PM2_ARGS",
"db": "node scripts/db.js",
"seo": "node scripts/seo.js",
"restore": "node scripts/elastic.js restore --output-index=vue_storefront_catalog_temp",
"mage2vs": "node scripts/mage2vs.js",
"restore": "node scripts/elastic.js restore",
"restore_it": "npm run restore -- --input-file=var/catalog_it.json --output-index=vue_storefront_catalog_it && npm run db rebuild -- --indexName=vue_storefront_catalog_it",
"restore_de": "npm run restore -- --input-file=var/catalog_de.json --output-index=vue_storefront_catalog_de && npm run db rebuild -- --indexName=vue_storefront_catalog_de",
"restore2main": "npm run restore -- --output-index=vue_storefront_catalog",
Expand Down Expand Up @@ -59,6 +60,7 @@
"cors": "^2.8.4",
"elasticdump": "^3.3.12",
"elasticsearch": "^13.3.1",
"email-check": "^1.1.0",
"express": "^4.16.3",
"graphql": "^0.10.1",
"graphql-tools": "^1.2.1",
Expand All @@ -68,11 +70,13 @@
"jwt-simple": "^0.5.1",
"kue": "^0.11.6",
"lodash": "^4.17.10",
"mage2vuestorefront": "git+https://github.com/DivanteLtd/mage2vuestorefront.git",
"magento2-rest-client": "github:DivanteLtd/magento2-rest-client",
"merge-graphql-schemas": "^1.5.2",
"migrate": "^1.5.0",
"mime-types": "^2.1.18",
"morgan": "^1.9.0",
"nodemailer": "^4.6.8",
"oauth-1.0a": "^1.0.1",
"pm2": "^2.10.4",
"request": "^2.85.0",
Expand Down
1 change: 1 addition & 0 deletions scripts/db.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ program
}

console.log('Done! Bye!')
process.exit(0)
})
})

Expand Down
163 changes: 163 additions & 0 deletions scripts/mage2vs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
const program = require('commander')
const config = require('config')
const spawn = require('child_process').spawn

function multiStoreConfig(apiConfig, storeCode) {
let confCopy = Object.assign({}, apiConfig)

if (storeCode && config.availableStores.indexOf(storeCode) >= 0)
{
if (config.magento2['api_' + storeCode]) {
confCopy = Object.assign({}, config.magento2['api_' + storeCode]) // we're to use the specific api configuration - maybe even separate magento instance
}
confCopy.url = confCopy.url + '/' + storeCode
} else {
if (storeCode) {
console.error('Unavailable store code', storeCode)
}
}
return confCopy
}


function exec(cmd, args, opts) {
return new Promise((resolve, reject) => {
let child = spawn(cmd, args, opts)
child.stdout.on('data', (data) => {
console.log(data.toString('utf8'));
});

child.stderr.on('data', (data) => {
console.log(data.toString('utf8'));
});

child.on('close', (code) => {
resolve(code)
});

child.on('error', (error) => {
console.error(errror)
reject(error)
});
})
}

program
.command('import')
.option('--store-code <storeCode>', 'storeCode in multistore setup', null)
.action((cmd) => {
const apiConfig = multiStoreConfig(config.magento2.api, cmd.storeCode)
let magentoConfig = {
TIME_TO_EXIT: 2000,
PRODUCTS_SPECIAL_PRICES: true,
MAGENTO_CONSUMER_KEY: apiConfig.consumerKey,
MAGENTO_CONSUMER_SECRET: apiConfig.consumerSecret,
MAGENTO_ACCESS_TOKEN: apiConfig.accessToken,
MAGENTO_ACCESS_TOKEN_SECRET: apiConfig.accessTokenSecret,
MAGENTO_URL: apiConfig.url,
INDEX_NAME: config.elasticsearch.indices[0]
}

if (cmd.storeCode) {
const storeView = config.storeViews[cmd.storeCode]
if (!storeView) {
console.error('Wrong storeCode provided - no such store in the config.storeViews[storeCode]', cmd.storeCode)
process.exit(-1)
} else {
magentoConfig.INDEX_NAME = storeView.elasticsearch.index;
}
}

const env = Object.assign({}, magentoConfig, process.env) // use process env as well
console.log('=== The mage2vuestorefront full reindex is about to start. Using the following Magento2 config ===', magentoConfig)

console.log(' == CREATING NEW DATABASE ==')
exec('node', [
'scripts/db.js',
'new',
`--indexName=${env.INDEX_NAME}`
], { env: env, shell: true }).then((res) => {

console.log(' == REVIEWS IMPORTER ==')
exec('node', [
'--harmony',
'node_modules/mage2vuestorefront/src/cli.js',
'reviews'
], { env: env, shell: true }).then((res) => {

console.log(' == CATEGORIES IMPORTER ==')
exec('node', [
'--harmony',
'node_modules/mage2vuestorefront/src/cli.js',
'categories',
'--removeNonExistent=true',
'--extendedCategories=true'
], { env: env, shell: true }).then((res) => {

console.log(' == PRODUCT-CATEGORIES IMPORTER ==')
exec('node', [
'--harmony',
'node_modules/mage2vuestorefront/src/cli.js',
'productcategories'
], { env: env, shell: true }).then((res) => {

console.log(' == ATTRIBUTES IMPORTER ==')
exec('node', [
'--harmony',
'node_modules/mage2vuestorefront/src/cli.js',
'attributes',
'--removeNonExistent=true'
], { env: env, shell: true }).then((res) => {

console.log(' == TAXRULE IMPORTER ==')
exec('node', [
'--harmony',
'node_modules/mage2vuestorefront/src/cli.js',
'taxrule',
'--removeNonExistent=true'
], { env: env, shell: true }).then((res) => {

console.log(' == PRODUCTS IMPORTER ==')
exec('node', [
'--harmony',
'node_modules/mage2vuestorefront/src/cli.js',
'products',
'--removeNonExistent=true',
'--partitions=1'
], { env: env, shell: true }).then((res) => {

console.log(' == REINDEXING DATABASE ==')
exec('node', [
'scripts/db.js',
'rebuild',
`--indexName=${env.INDEX_NAME}`
], { env: env, shell: true }).then((res) => {
console.log('Done! Bye Bye!')
process.exit(0)
});
})
})
})
})
})
})
})
})


program
.on('command:*', () => {
console.error('Invalid command: %s\nSee --help for a list of available commands.', program.args.join(' '));
process.exit(1);
});

program
.parse(process.argv)

process.on('unhandledRejection', (reason, p) => {
console.log("Unhandled Rejection at: Promise ", p, " reason: ", reason)
})

process.on('uncaughtException', function(exception) {
console.log(exception)
})
91 changes: 91 additions & 0 deletions src/api/extensions/mail-service/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import { apiStatus } from '../../../lib/util'
import { Router } from 'express'
import EmailCheck from 'email-check'
import jwt from 'jwt-simple'
import NodeMailer from 'nodemailer'

module.exports = ({ config }) => {
const msApi = Router()
let token

/**
* GET send token to authorize email
*/
msApi.get('/get-token', (req, res) => {
token = jwt.encode(Date.now(), config.extensions.mailService.secretString)
apiStatus(res, token, 200)
})

/**
* POST send an email
*/
msApi.post('/send-email', (req, res) => {
const userData = req.body
if (!userData.token || userData.token !== token) {
apiStatus(res, 'Email is not authorized!', 500)
}
const { host, port, secure, user, pass } = config.extensions.mailService.transport
if (!host || !port || !user || !pass) {
apiStatus(res, 'No transport is defined for mail service!', 500)
}
if (!userData.sourceAddress) {
apiStatus(res, 'Source email address is not provided!', 500)
return
}
if (!userData.targetAddress) {
apiStatus(res, 'Target email address is not provided!', 500)
return
}
// Check if email address we're sending to is from the white list from config
const whiteList = config.extensions.mailService.targetAddressWhitelist
const email = userData.confirmation ? userData.sourceAddress : userData.targetAddress
if (!whiteList.includes(email)) {
apiStatus(res, `Target email address (${email}) is not from the whitelist!`, 500)
return
}

// check if provided email addresses actually exist
EmailCheck(userData.sourceAddress)
.then(response => {
if (response) return EmailCheck(userData.targetAddress)
else {
apiStatus(res, 'Source email address is invalid!', 500)
return
}
})
.then(response => {
if (response) {
let transporter = NodeMailer.createTransport({
host,
port,
secure,
auth: {
user,
pass
}
})
const mailOptions = {
from: userData.sourceAddress,
to: userData.targetAddress,
subject: userData.subject,
text: userData.emailText
}
transporter.sendMail(mailOptions, (error) => {
if (error) {
apiStatus(res, error, 500)
return
}
apiStatus(res, 'OK', 200)
transporter.close()
})
} else {
apiStatus(res, 'Target email address is invalid!', 500)
}
})
.catch(() => {
apiStatus(res, 'Invalid email address is provided!', 500)
})
})

return msApi
}
6 changes: 5 additions & 1 deletion src/graphql/resolvers.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@ import path from 'path';
import config from 'config';
import { fileLoader, mergeResolvers } from 'merge-graphql-schemas';

const resolversArray = fileLoader(
const coreResolvers = fileLoader(
path.join(__dirname, `./${config.server.searchEngine}/**/resolver.js`)
);
const extensionsResolvers = fileLoader(
path.join(__dirname, `../api/extensions/**/resolver.js`)
);
const resolversArray = coreResolvers.concat(extensionsResolvers)

export default mergeResolvers(resolversArray, { all: true });
Loading

0 comments on commit 92c96a6

Please sign in to comment.