Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

homebridge-fordpass

Package Overview
Dependencies
Maintainers
1
Versions
46
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

homebridge-fordpass - npm Package Compare versions

Comparing version 1.7.0 to 1.7.1

207

dist/fordpass-connection.js

@@ -16,9 +16,28 @@ "use strict";

exports.Connection = void 0;
const querystring_1 = __importDefault(require("querystring"));
const axios_1 = __importDefault(require("axios"));
const authUrl = 'https://sso.ci.ford.com/';
const crypto_1 = __importDefault(require("crypto"));
const base64url_1 = __importDefault(require("base64url"));
const url_1 = require("url");
const vehiclesUrl = 'https://services.cx.ford.com/api/dashboard/v1/users/vehicles';
const catWithRefreshTokenUrl = 'https://api.mps.ford.com/api/token/v2/cat-with-refresh-token';
const catWithCIAccessTokenUrl = 'https://api.mps.ford.com/api/token/v2/cat-with-ci-access-token';
const authorizeUrl = 'https://sso.ci.ford.com/v1.0/endpoint/default/authorize';
const tokenUrl = 'https://sso.ci.ford.com/oidc/endpoint/default/token';
const defaultAppId = '71A3AD0A-CF46-4CCF-B473-FC7FE5BC4592';
const clientId = '9fb503e0-715b-47e8-adfd-ad4b7770f73b';
const userAgent = 'FordPass/5 CFNetwork/1333.0.4 Darwin/21.5.0';
const randomStr = (len) => {
let result = '';
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
const charactersLength = characters.length;
for (let i = 0; i < len; i++) {
result += characters.charAt(Math.floor(Math.random() * charactersLength));
}
return result;
};
const codeChallenge = (str) => {
const hash = crypto_1.default.createHash('sha256');
hash.update(str);
return (0, base64url_1.default)(hash.digest());
};
const headers = {

@@ -36,44 +55,2 @@ 'User-Agent': userAgent,

}
auth() {
return __awaiter(this, void 0, void 0, function* () {
const url = authUrl + 'oidc/endpoint/default/token';
const options = {
method: 'POST',
url: url,
headers: Object.assign({ 'Content-Type': 'application/x-www-form-urlencoded' }, headers),
data: querystring_1.default.stringify({
client_id: clientId,
grant_type: 'password',
username: this.config.username,
password: this.config.password,
}),
};
try {
const result = yield (0, axios_1.default)(options);
if (result.status === 200 && result.data.access_token) {
const nextResult = yield axios_1.default.post('https://api.mps.ford.com/api/token/v2/cat-with-ci-access-token', {
ciToken: result.data.access_token,
}, {
headers: Object.assign({ 'Content-Type': 'application/json', 'Application-Id': this.applicationId }, headers),
});
if (nextResult.status === 200 && nextResult.data.access_token) {
this.config.access_token = nextResult.data.access_token;
this.config.refresh_token = nextResult.data.refresh_token;
return nextResult.data;
}
else {
this.log.error(`Auth failed with status: ${nextResult.status}`);
}
}
else {
this.log.error(`Auth failed with status: ${result.status}`);
}
return;
}
catch (error) {
this.log.error(`Auth failed with error: ${error.code || error.response.status}`);
return;
}
});
}
refreshAuth() {

@@ -83,3 +60,3 @@ return __awaiter(this, void 0, void 0, function* () {

if (this.config.refresh_token) {
const result = yield axios_1.default.post('https://api.mps.ford.com/api/token/v2/cat-with-refresh-token', {
const result = yield axios_1.default.post(catWithRefreshTokenUrl, {
refresh_token: this.config.refresh_token,

@@ -135,4 +112,144 @@ }, {

}
auth() {
var _a;
return __awaiter(this, void 0, void 0, function* () {
const numOfRedirects = 2;
const code = randomStr(43);
let cookies = undefined;
const url = `${authorizeUrl}?redirect_uri=fordapp://userauthorized&response_type=code&scope=openid&max_age=3600&client_id=9fb503e0-715b-47e8-adfd-ad4b7770f73b&code_challenge=${codeChallenge(code)}&code_challenge_method=S256`;
let nextUrl = url;
for (let i = 0; i < numOfRedirects; i++) {
const options = {
method: 'GET',
maxRedirects: 0,
url: nextUrl,
headers: Object.assign({}, headers),
};
if (options.headers && cookies) {
options.headers.cookie = cookies;
}
try {
yield (0, axios_1.default)(options);
throw new Error('Authentication failed');
}
catch (err) {
if (((_a = err === null || err === void 0 ? void 0 : err.response) === null || _a === void 0 ? void 0 : _a.status) === 302) {
nextUrl = err.response.headers.location;
cookies = err.response.headers['set-cookie'];
}
else {
this.log.error(`Auth failed with status: ${err.status}`);
}
}
}
return this.doLogin(nextUrl, code, cookies);
});
}
doLogin(url, code_verifier, cookies) {
var _a;
return __awaiter(this, void 0, void 0, function* () {
if (!this.config.username || !this.config.password) {
throw new Error('Username or password is empty in config');
}
const options = {
method: 'POST',
maxRedirects: 0,
url: url,
headers: Object.assign({ 'Content-Type': 'application/x-www-form-urlencoded', cookie: cookies }, headers),
data: new url_1.URLSearchParams({
operation: 'verify',
'login-form-type': 'pwd',
username: this.config.username,
password: this.config.password,
}).toString(),
};
try {
yield (0, axios_1.default)(options);
throw new Error('Authentication failed');
}
catch (err) {
if (((_a = err === null || err === void 0 ? void 0 : err.response) === null || _a === void 0 ? void 0 : _a.status) === 302) {
const nextUrl = err.response.headers.location;
const cookies = err.response.headers['set-cookie'];
return this.getAuthorizationCode(nextUrl, code_verifier, cookies);
}
else {
this.log.error(`Auth failed with status: ${err.status}`);
}
}
});
}
getAuthorizationCode(url, code_verifier, cookies) {
var _a;
return __awaiter(this, void 0, void 0, function* () {
const options = {
method: 'GET',
maxRedirects: 0,
url: url,
headers: Object.assign({ cookie: cookies }, headers),
};
try {
yield (0, axios_1.default)(options);
throw new Error('Authentication failed');
}
catch (err) {
if (((_a = err === null || err === void 0 ? void 0 : err.response) === null || _a === void 0 ? void 0 : _a.status) === 302) {
const nextUrl = err.response.headers.location;
const params = new url_1.URLSearchParams(nextUrl.split('?')[1]);
const code = params.get('code');
if (code) {
return this.getAccessToken(code, code_verifier);
}
}
else {
this.log.error(`Auth failed with status: ${err.status}`);
}
}
});
}
getAccessToken(code, code_verifier) {
return __awaiter(this, void 0, void 0, function* () {
const options = {
method: 'POST',
url: tokenUrl,
headers: Object.assign({ 'Content-Type': 'application/x-www-form-urlencoded' }, headers),
data: new url_1.URLSearchParams({
client_id: clientId,
grant_type: 'authorization_code',
scope: 'openid',
redirect_uri: 'fordapp://userauthorized',
code: code,
code_verifier: code_verifier,
}).toString(),
};
try {
const res = yield (0, axios_1.default)(options);
if (res.status === 200 && res.data.access_token) {
return this.getRefreshToken(res.data.access_token);
}
}
catch (err) {
this.log.error(`Auth failed with error: ${err}`);
}
});
}
getRefreshToken(access_token) {
return __awaiter(this, void 0, void 0, function* () {
const res = yield axios_1.default.post(catWithCIAccessTokenUrl, {
ciToken: access_token,
}, {
headers: Object.assign({ 'Content-Type': 'application/json', 'Application-Id': this.applicationId }, headers),
});
if (res.status === 200 && res.data.access_token) {
this.config.access_token = res.data.access_token;
this.config.refresh_token = res.data.refresh_token;
return res.data;
}
else {
this.log.error(`Auth failed with status: ${res.status}`);
}
});
}
}
exports.Connection = Connection;
//# sourceMappingURL=fordpass-connection.js.map

@@ -98,2 +98,5 @@ "use strict";

callback(undefined, lockNumber);
if (!this.config.access_token) {
return;
}
const status = yield vehicle.status();

@@ -130,2 +133,5 @@ if (status) {

callback(undefined, engineStatus);
if (!this.config.access_token) {
return;
}
const status = yield vehicle.status();

@@ -159,2 +165,5 @@ if (status) {

callback(undefined, level);
if (!this.config.access_token) {
return;
}
const status = yield vehicle.status();

@@ -161,0 +170,0 @@ if (status) {

{
"displayName": "Homebridge FordPass",
"name": "homebridge-fordpass",
"version": "1.7.0",
"version": "1.7.1",
"description": "Fordpass plugin for homebridge: https://homebridge.io/",

@@ -53,3 +53,4 @@ "main": "dist/index.js",

"dependencies": {
"axios": "^0.27.2"
"axios": "^0.27.2",
"base64url": "^3.0.1"
},

@@ -56,0 +57,0 @@ "devDependencies": {

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc