feat(high-mobility): Introduce get vehicle location action

This commit is contained in:
Faruk AYDIN
2023-09-19 21:11:05 +02:00
parent ba17cde59b
commit d1e7b6b9eb
11 changed files with 279 additions and 0 deletions

View File

@@ -0,0 +1,15 @@
import defineAction from '../../../../helpers/define-action';
export default defineAction({
name: 'Get Vehicle Location',
key: 'getVehicleLocation',
description: 'Get the location of a vehicle',
async run($) {
const response = await $.http.get(
`https://sandbox.rest-api.high-mobility.com/v5/vehicle_location`
);
$.setActionItem({ raw: response.data });
},
});

View File

@@ -0,0 +1,3 @@
import getVehicleLocation from './get-vehicle-location';
export default [getVehicleLocation];

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32" fill="none">
<path fill-rule="evenodd" clip-rule="evenodd" d="M10.1098 0H21.9778C27.5162 0 32.0436 4.52747 31.9997 10.0659V21.9341C31.9997 27.4725 27.4723 32 21.9338 32H10.0658C4.52743 32 0 27.4725 0 21.9341V10.0659C0 4.52747 4.52743 0 10.1098 0ZM9.58232 17.1868H14.4174C14.9889 17.1868 15.4724 16.7033 15.4724 16.1319C15.4724 15.5604 14.9889 15.0769 14.4174 15.0769H9.58232V10.4615C9.58232 9.89011 9.09881 9.40659 8.52739 9.40659C7.95597 9.40659 7.47245 9.89011 7.47245 10.4615V21.5824C7.47245 22.1538 7.95597 22.6374 8.52739 22.6374C9.09881 22.6374 9.58232 22.1538 9.58232 21.5824V17.1868ZM23.5163 22.6374C24.0877 22.6374 24.5712 22.1538 24.5712 21.5824H24.5674V10.4691C24.5712 10.4336 24.5731 10.3975 24.5731 10.361C24.5731 9.80393 24.1216 9.35237 23.5645 9.35237C23.2507 9.35237 22.9704 9.49569 22.7854 9.72044L22.7851 9.7192L17.4943 14.4615C17.0548 14.8571 17.0108 15.5165 17.4064 15.956C17.6262 16.1758 17.8899 16.3077 18.1976 16.3077C18.4614 16.3077 18.6811 16.2198 18.9009 16.044L22.4613 12.8352V21.5824C22.4613 22.1538 22.9448 22.6374 23.5163 22.6374Z" fill="#0A4B58"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1,21 @@
import { IField, IGlobalVariable } from '@automatisch/types';
import { URLSearchParams } from 'url';
export default async function generateAuthUrl($: IGlobalVariable) {
const oauthRedirectUrlField = $.app.auth.fields.find(
(field: IField) => field.key == 'oAuthRedirectUrl'
);
const redirectUri = oauthRedirectUrlField.value as string;
const searchParams = new URLSearchParams({
response_type: 'code',
client_id: $.auth.data.clientId as string,
redirect_uri: redirectUri,
});
const url = `https://sandbox.owner-panel.high-mobility.com/oauth/new?${searchParams.toString()}`;
await $.auth.set({
url,
});
}

View File

@@ -0,0 +1,93 @@
import generateAuthUrl from './generate-auth-url';
import verifyCredentials from './verify-credentials';
import isStillVerified from './is-still-verified';
import refreshToken from './refresh-token';
export default {
fields: [
{
key: 'oAuthRedirectUrl',
label: 'OAuth Redirect URL',
type: 'string' as const,
required: true,
readOnly: true,
value: '{WEB_APP_URL}/app/high-mobility/connections/add',
placeholder: null,
description:
'When asked to input an OAuth callback or redirect URL in High Mobility OAuth, enter the URL above.',
clickToCopy: true,
},
{
key: 'screenName',
label: 'Screen Name',
type: 'string' as const,
required: true,
readOnly: false,
value: null,
placeholder: null,
description:
'Screen name of your connection to be used on Automatisch UI.',
clickToCopy: false,
},
{
key: 'clientId',
label: 'Client ID',
type: 'string' as const,
required: true,
readOnly: false,
value: null,
placeholder: null,
description: 'Client ID of your High Mobility OAuth app.',
clickToCopy: false,
},
{
key: 'clientSecret',
label: 'Client Secret',
type: 'string' as const,
required: true,
readOnly: false,
value: null,
placeholder: null,
description: 'Client Secret of your High Mobility OAuth app.',
clickToCopy: false,
},
{
key: 'privateKey',
label: 'Private Key',
type: 'string' as const,
required: true,
readOnly: false,
value: null,
placeholder: null,
description: 'Private Key of your High Mobility OAuth app.',
clickToCopy: false,
},
{
key: 'appId',
label: 'App ID',
type: 'string' as const,
required: true,
readOnly: false,
value: null,
placeholder: null,
description: 'App ID of your High Mobility OAuth app.',
clickToCopy: false,
},
{
key: 'clientSerialNumber',
label: 'Client Serial Number',
type: 'string' as const,
required: true,
readOnly: false,
value: null,
placeholder: null,
description: 'Client Serial Number of your High Mobility OAuth app.',
clickToCopy: false,
},
],
generateAuthUrl,
verifyCredentials,
isStillVerified,
refreshToken,
};

View File

@@ -0,0 +1,9 @@
import { IGlobalVariable } from '@automatisch/types';
import getVehicleInfo from '../common/get-vehicle-info';
const isStillVerified = async ($: IGlobalVariable) => {
const user = await getVehicleInfo($);
return !!user;
};
export default isStillVerified;

View File

@@ -0,0 +1,27 @@
import { IGlobalVariable } from '@automatisch/types';
const refreshToken = async ($: IGlobalVariable) => {
const payload = {
client_id: $.auth.data.clientId as string,
client_secret: $.auth.data.clientSecret as string,
refresh_token: $.auth.data.refreshToken as string,
grant_type: 'refresh_token',
};
const { data } = await $.http.post(
'https://sandbox.api.high-mobility.com/v1/access_tokens',
payload
);
await $.auth.set({
tokenType: data.token_type,
status: data.status,
scope: data.scope,
refreshToken: data.refresh_token,
expiresIn: data.expires_in,
accessToken: data.access_token,
authorizationId: data.authorization_id,
});
};
export default refreshToken;

View File

@@ -0,0 +1,36 @@
import { IGlobalVariable, IField } from '@automatisch/types';
import { URLSearchParams } from 'url';
const verifyCredentials = async ($: IGlobalVariable) => {
const oauthRedirectUrlField = $.app.auth.fields.find(
(field: IField) => field.key == 'oAuthRedirectUrl'
);
const redirectUri = oauthRedirectUrlField.value as string;
const payload = {
client_id: $.auth.data.clientId as string,
client_secret: $.auth.data.clientSecret as string,
code: $.auth.data.code as string,
redirect_uri: redirectUri,
grant_type: 'authorization_code',
};
const response = await $.http.post(
'https://sandbox.api.high-mobility.com/v1/access_tokens',
payload
);
const responseData = Object.fromEntries(new URLSearchParams(response.data));
await $.auth.set({
tokenType: responseData.token_type,
status: responseData.status,
scope: responseData.scope,
refreshToken: responseData.refresh_token,
expiresIn: responseData.expires_in,
accessToken: responseData.access_token,
authorizationId: responseData.authorization_id,
});
};
export default verifyCredentials;

View File

@@ -0,0 +1,41 @@
import { TBeforeRequest } from '@automatisch/types';
import jwt from 'jsonwebtoken';
import { v4 as uuidv4 } from 'uuid';
const addAuthHeader: TBeforeRequest = ($, requestConfig) => {
const { accessToken } = $.auth.data;
const { url } = requestConfig;
if (accessToken && url === '/v1/vehicleinfo') {
requestConfig.headers.Authorization = `Bearer ${accessToken}`;
return requestConfig;
}
const config = {
version: '3.0',
type: 'rest_api',
private_key: ($.auth.data.privateKey as string).replaceAll('\\n', '\n'),
app_uri: 'https://sandbox.rest-api.high-mobility.com/v5',
app_id: $.auth.data.appId as string,
client_serial_number: $.auth.data.clientSerialNumber as string,
};
const payload = {
ver: config.version,
aud: config.app_uri,
iss: config.client_serial_number,
iat: Math.round(Date.now() / 1000),
jti: uuidv4(),
sub: $.auth.data.accessToken,
};
const priv = Buffer.from(config.private_key, 'utf8');
const token = jwt.sign(payload, priv, { algorithm: 'ES256' });
requestConfig.headers.Authorization = `Bearer ${token}`;
return requestConfig;
};
export default addAuthHeader;

View File

@@ -0,0 +1,13 @@
import { IGlobalVariable, IJSONObject } from '@automatisch/types';
const getVehicleInfo = async ($: IGlobalVariable): Promise<IJSONObject> => {
const response = await $.http.get(
'https://sandbox.api.high-mobility.com/v1/vehicleinfo'
);
const currentVehicle = response.data;
return currentVehicle;
};
export default getVehicleInfo;

View File

@@ -0,0 +1,18 @@
import defineApp from '../../helpers/define-app';
import addAuthHeader from './common/add-auth-header';
import auth from './auth';
import actions from './actions';
export default defineApp({
name: 'High Mobility',
key: 'high-mobility',
iconUrl: '{BASE_URL}/apps/high-mobility/assets/favicon.svg',
authDocUrl: 'https://automatisch.io/docs/apps/high-mobility/connection',
supportsConnections: true,
baseUrl: 'https://high-mobility.com',
apiBaseUrl: 'https://api.high-mobility.com',
primaryColor: '000000',
beforeRequest: [addAuthHeader],
auth,
actions,
});