Comparing version 2.0.0 to 2.0.1
@@ -7,2 +7,6 @@ 'use strict'; | ||
var _qs = require('qs'); | ||
var _qs2 = _interopRequireDefault(_qs); | ||
var _v = require('../routes/v4'); | ||
@@ -22,2 +26,6 @@ | ||
var _AuthServer = require('./auth/AuthServer'); | ||
var _AuthServer2 = _interopRequireDefault(_AuthServer); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
@@ -94,2 +102,37 @@ | ||
}, { | ||
key: 'setState', | ||
value: function setState(state) { | ||
this._state = state; | ||
return this; | ||
} | ||
}, { | ||
key: 'getState', | ||
value: function getState(state) { | ||
return this._state; | ||
} | ||
}, { | ||
key: 'getAuthUrl', | ||
value: function getAuthUrl() { | ||
var mode = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'popup'; | ||
var baseUrl = 'https://www.amocrm.ru/oauth', | ||
client_id = this._options.client_id, | ||
params = { | ||
client_id: client_id, | ||
mode: mode | ||
}, | ||
state = this.getState(); | ||
if (state) { | ||
params.state = state; | ||
} | ||
var paramsStr = _qs2.default.stringify(params), | ||
url = baseUrl + '?' + paramsStr; | ||
return url; | ||
} | ||
}, { | ||
key: 'getToken', | ||
value: function getToken() { | ||
return this._request.getToken(); | ||
} | ||
}, { | ||
key: 'fetchToken', | ||
@@ -162,5 +205,26 @@ value: function fetchToken() { | ||
}, { | ||
key: 'waitUserAuth', | ||
value: function waitUserAuth() { | ||
var _this5 = this; | ||
if (this._server) { | ||
return; | ||
} | ||
var server = new _AuthServer2.default(_extends({}, this._options.server, { | ||
state: this.getState() | ||
})); | ||
this._server = server; | ||
return new Promise(function (resolve) { | ||
server.on('code', function (code) { | ||
server.stop(); | ||
_this5._server = null; | ||
_this5.setCode(code).then(resolve); | ||
}); | ||
server.run(); | ||
}); | ||
} | ||
}, { | ||
key: 'connect', | ||
value: function connect() { | ||
var _this5 = this; | ||
var _this6 = this; | ||
@@ -173,4 +237,14 @@ if (this._isConnected) { | ||
this._lastConnectionRequestAt = new Date(); | ||
var requestPromise = this._isConnected ? this.refreshToken() : this.fetchToken(); | ||
var requestPromise = void 0; | ||
if (this._isConnected) { | ||
requestPromise = this.refreshToken(); | ||
} else if (this._options.code) { | ||
requestPromise = this.fetchToken(); | ||
} else if (this._options.server) { | ||
return this.waitUserAuth(); | ||
} else { | ||
return; | ||
} | ||
return requestPromise.then(function (response) { | ||
@@ -181,4 +255,4 @@ var _response$data = response.data, | ||
if (data && data.token_type) { | ||
_this5._lastRequestAt = new Date(); | ||
_this5.triggerEvent('connected', _this5); | ||
_this6._lastRequestAt = new Date(); | ||
_this6.triggerEvent('connected', _this6); | ||
return true; | ||
@@ -190,4 +264,4 @@ } | ||
_this5.triggerEvent('authError', e, _this5); | ||
_this5.triggerEvent('error', e, _this5); | ||
_this6.triggerEvent('authError', e, _this6); | ||
_this6.triggerEvent('error', e, _this6); | ||
@@ -194,0 +268,0 @@ return Promise.reject(e); |
{ | ||
"name": "amocrm-js", | ||
"version": "2.0.0", | ||
"version": "2.0.1", | ||
"description": "JS Library for AmoCRM", | ||
@@ -5,0 +5,0 @@ "main": "dist/AmoCRM.js", |
103
README.md
@@ -25,2 +25,14 @@ # AmoCRM | ||
## Подключение к CRM | ||
Подключение возможно: | ||
1. По заранее известному коду авторизации | ||
(например, с помощью [упрощённой авторизации](https://www.amocrm.ru/developers/content/oauth/easy-auth)) | ||
2. С помощью встроенного OAuth-сервера (см. пример ниже) | ||
### Код авторизации известен | ||
Его можно получить с помощью упрощенной авторизации или самостоятельно написанного обработчика | ||
адреса интеграции (redirectUri). | ||
```js | ||
@@ -43,5 +55,84 @@ const AmoCRM = require( 'amocrm-js' ); | ||
}); | ||
``` | ||
### Встроенный OAuth-сервер | ||
В AmoCRM API у кода авторизации есть особенность: его можно использовать __только один раз__ для получения | ||
токена. Последующие запросы на получение токена будут выдавать ошибку. | ||
Чтобы облегчить процесс получения токена, в данный пакет встроен OAuth-сервер, | ||
который может обрабатывать указанный адрес перенаправления. | ||
Пример настройки без параметра *code*: | ||
```js | ||
const AmoCRM = require( 'amocrm-js' ); | ||
const crm = new AmoCRM({ | ||
// логин пользователя в портале, где адрес портала domain.amocrm.ru | ||
domain: 'domain', // может быть указан полный домен вида domain.amocrm.ru, domain.amocrm.com | ||
/* | ||
Информация об интеграции (подробности подключения | ||
описаны на https://www.amocrm.ru/developers/content/oauth/step-by-step) | ||
*/ | ||
auth: { | ||
client_id: 'clientId', // ID интеграции | ||
client_secret: 'clientSecret', // Секретный ключ | ||
redirect_uri: 'redirectUri', // Ссылка для перенаправления, | ||
server: { | ||
// порт, на котором запустится сервер авторизации | ||
port: 3000 | ||
} | ||
}, | ||
}); | ||
``` | ||
Как выглядит процесс авторизации: | ||
1. Сервер ожидает перехода пользователя по адресу: *crm.connection.getAuthUrl(mode)* | ||
2. При успешном переходе пользователь перенаправляется на {redirectUri}, заданный в интеграции | ||
3. Сервер авторизации перехватывает запрос на {redirectUri} | ||
(как это сделать, описано ниже), извлекает код авторизации и | ||
с помощью *crm.connection.setCode(code)* автоматически получает токен для работы | ||
#### Использование в целях разработки | ||
Один из простых способ разработки интеграции: библиотека-сервис [ngrok](https://ngrok.com). | ||
Пакет перенаправляет трафик с вашего компьютера на заданный публичный IP, который можно задать в | ||
адресе интеграции. | ||
После установки пакета: | ||
1. Выполните в терминале команду: ```ngrok http 3001``` | ||
2. Полученный в результат адрес вида https://311e923c5281.ngrok.io указываем в настройках интеграции AmoCRM | ||
3. В настройках указываем номер порта (в нашем примере 3001) и полученный ngrok-адрес в {auth.redirect_uri} | ||
4. Получаем адрес ссылке, по которой необходимо будет перейти через *crm.connection.getAuthUrl()* | ||
5. Переходим по ссылке, после этого код автоматически установится и библиотека запросит новый токен | ||
Пример настроек: | ||
```js | ||
const crm = new AmoCRM({ | ||
// ... | ||
auth: { | ||
// ... | ||
redirect_uri: 'https://311e923c5281.ngrok.io', | ||
server: { | ||
port: 3001 | ||
} | ||
}, | ||
}); | ||
``` | ||
#### Разработка на production-сервере | ||
Для работы сервера авторизации на «боевом» хостинге ему нужно выполнение условий: | ||
1. Публичный IP-адрес, на котором находится проект | ||
2. Порт сервера авторизации, указанный в настройках данной библиотеки (*auth.server.port*), | ||
открыт для внешних подключений или работает прокси-переадресация в настройках виртуального хоста. | ||
После остаётся только заменить адрес {redirectUri} на адрес | ||
вашего хоста в настройках библиотеки и интеграции. | ||
## Запросы к порталу | ||
@@ -114,3 +205,13 @@ | ||
Вызывается автоматически при необходимости обновления. | ||
3. *crm.connection.getAuthUrl(mode)* - возвращает адрес ссылки, по которой должен перейти пользователь. | ||
Параметр mode отвечает за обработку запроса на Redirect URI. | ||
В случае popup – окно авторизации будет закрыто, а переход на Redirect URI будет выполнен в основном окне. | ||
В случае передачи значения post_message – перенаправление произойдет в окне, которое было открыто, после обработки кода авторизации вам нужно закрыть окно | ||
4. *crm.connection.setState(state)* - задаёт произвольную строку состояния | ||
(используется для проверки подлинности во встроенном сервере авторизации) | ||
5. *crm.connection.getState(state)* - возвращает строку состояния | ||
6. *crm.connection.getToken()* - возвращает текущий токен авторизации | ||
7. *crm.connection.setToken( token, responseAt )* - задаёт токен авторизации. responseAt - экземпляр Date, | ||
когда токен был получен (это не дата истечения срока годности). | ||
## Работа с событиями | ||
@@ -117,0 +218,0 @@ |
@@ -22,2 +22,24 @@ import AmoCRM from '../src/AmoCRM'; | ||
}); | ||
fit( 'should auth with server', done => { | ||
client.connection.setState( 'helloworld' ); | ||
const url = client.connection.getAuthUrl(); | ||
console.log({ | ||
url | ||
}); | ||
client.connection.connect() | ||
.then( response => { | ||
return client.connection.refreshToken(); | ||
}) | ||
.then( response => console.log( response.data )) | ||
.then( done ); | ||
}, 60 * 1000 ); | ||
it( 'should return authUrl', done => { | ||
const url = client.connection.getAuthUrl(); | ||
console.log({ | ||
url | ||
}); | ||
done(); | ||
}); | ||
}); |
@@ -22,3 +22,3 @@ import AmoCRM from '../dist/AmoCRM'; | ||
}); | ||
fit( 'should create custom request', done => { | ||
it( 'should create custom request', done => { | ||
client.request.get( '/api/v4/leads' ) | ||
@@ -25,0 +25,0 @@ .then( done ); |
'use strict'; | ||
import qs from 'qs'; | ||
import schema from '../routes/v4'; | ||
@@ -7,2 +8,3 @@ import EventResource from './EventResource'; | ||
import PrivateDomainRequest from "./requests/domain/PrivateDomainRequest"; | ||
import AuthServer from "./auth/AuthServer"; | ||
@@ -69,2 +71,31 @@ class AmoConnection extends EventResource { | ||
setState( state ) { | ||
this._state = state; | ||
return this; | ||
} | ||
getState( state ) { | ||
return this._state; | ||
} | ||
getAuthUrl( mode = 'popup' ) { | ||
const baseUrl = 'https://www.amocrm.ru/oauth', | ||
{ client_id } = this._options, | ||
params = { | ||
client_id, | ||
mode | ||
}, | ||
state = this.getState(); | ||
if ( state ) { | ||
params.state = state; | ||
} | ||
const paramsStr = qs.stringify( params ), | ||
url = `${baseUrl}?${paramsStr}`; | ||
return url; | ||
} | ||
getToken() { | ||
return this._request.getToken(); | ||
} | ||
fetchToken() { | ||
@@ -130,2 +161,22 @@ this.triggerEvent( 'beforeFetchToken', this ); | ||
waitUserAuth() { | ||
if ( this._server ) { | ||
return; | ||
} | ||
const server = new AuthServer({ | ||
...this._options.server, | ||
state: this.getState() | ||
}); | ||
this._server = server; | ||
return new Promise( resolve => { | ||
server.on('code', code => { | ||
server.stop(); | ||
this._server = null; | ||
this.setCode( code ) | ||
.then( resolve ); | ||
}); | ||
server.run(); | ||
}) | ||
} | ||
connect() { | ||
@@ -138,4 +189,17 @@ if ( this._isConnected ) { | ||
this._lastConnectionRequestAt = new Date; | ||
const requestPromise = this._isConnected ? this.refreshToken() : this.fetchToken(); | ||
let requestPromise; | ||
if ( this._isConnected ) { | ||
requestPromise = this.refreshToken(); | ||
} | ||
else if ( this._options.code ) { | ||
requestPromise = this.fetchToken(); | ||
} | ||
else if ( this._options.server ) { | ||
return this.waitUserAuth(); | ||
} | ||
else { | ||
return; | ||
} | ||
return requestPromise | ||
@@ -142,0 +206,0 @@ .then( response => { |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
198184
129
4066
247
11