Skip to content

Commit

Permalink
proxy auth and service for costco figo SF
Browse files Browse the repository at this point in the history
  • Loading branch information
pgilmore-phi committed Nov 7, 2024
1 parent 524abfe commit 6221b74
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 113 deletions.
49 changes: 22 additions & 27 deletions tools/appbuilder/actions/costco-figo-proxy/authentication.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,33 +35,31 @@ async function main(params) {
// log parameters, only if params.LOG_LEVEL === 'debug'
logger.error(stringParameters(params))
logger.error(stringParameters(cache))

// check for missing request input parameters and headers
const requiredParams = [ 'SALESFORCE_CLIENT_ID' , 'SALESFORCE_CLIENT_SECRET', 'SALESFORCE_AUTH_URI', 'SALESFORCE_ACCOUNT_ID']
const requiredParams = [ 'COSTCO_CLIENT_ID' , 'COSTCO_CLIENT_SECRET', 'COSTCO_AUTH_URI', 'COSTCO_USERNAME', 'COSTCO_PASSWORD']
const requiredHeaders = []
const errorMessage = checkMissingRequestInputs(params, requiredParams, requiredHeaders)
if (errorMessage) {
// return and log client errors
return errorResponse(400, errorMessage, logger)
}

const authUrl = new URL('/v2/token', params.SALESFORCE_AUTH_URI);
const authUrl = new URL('/services/oauth2/token', params.COSTCO_AUTH_URI);
const token = await getToken(
params.SALESFORCE_CLIENT_ID,
params.SALESFORCE_CLIENT_SECRET,
params.SALESFORCE_ACCOUNT_ID,
params.SALESFORCE_SCOPES || false,
params.COSTCO_CLIENT_ID,
params.COSTCO_CLIENT_SECRET,
params.COSTCO_USERNAME,
params.COSTCO_PASSWORD,
authUrl.toString()
);

if (!token) {
return errorResponse(401, 'Authenticaction failed', logger)
}

const body = {SALESFORCE_TOKEN: token, ...params}
return {COSTCO_TOKEN: token, ...params}

return {statusCode: 200, body: body}
//return errorResponse(500, 'server error', logger)
} catch (error) {
// log any server errors
logger.error(error)
Expand All @@ -70,41 +68,38 @@ async function main(params) {
}
}

async function getToken(user, key, accountId, scope, authUrl) {
async function getToken(client_id, client_secret, username, password, authUrl) {
const now = Date.now();
if (cache.date === undefined || now - cache.date > 60 * 60 * 3) {
cache.date = now;
cache.token = await fetchToken(user, key, accountId, scope, authUrl);
cache.token = await fetchToken(client_id, client_secret, username, password, authUrl);
}

return cache.token;
}

async function fetchToken(client_id, client_secret, account_id, scope, authUrl) {
const data ={
"grant_type": "client_credentials",
"client_id": client_id,
"client_secret": client_secret,
"account_id": account_id
}

if (scope) {
data.scope = scope;
}
async function fetchToken(client_id, client_secret, username, password, authUrl) {
logger.info('authUrl', authUrl)
logger.info('client_id', client_id)
const data = new URLSearchParams();
data.append('grant_type', 'password');
data.append('client_id', client_id);
data.append('client_secret', client_secret);
data.append('username', username);
data.append('password', password);

logger.debug('data', data)
const res = await fetch(authUrl, {
method: 'POST',
body: JSON.stringify(data),
headers: { 'Content-Type': 'application/json' }
body: data,
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
})

if (res.status !== 200 && res.status !== 401 && res.status !== 403 && res.status !== 404) {
throw Error(`unexpected error with status '${res.status}' from '${authUrl.toString()}', please report this error`)
}

const response = await (res.json())
logger.debug('response', response)
logger.info('response', response)

return response.access_token;
}
Expand Down
113 changes: 37 additions & 76 deletions tools/appbuilder/actions/costco-figo-proxy/service.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,104 +21,65 @@ let logger;

// main function that will be executed by Adobe I/O Runtime
async function main(params) {
// create a Logger
logger = Core.Logger('main', { level: params.LOG_LEVEL || 'info' })

try {
// 'info' is the default level if not set
logger.info('Calling the main action')

// log parameters, only if params.LOG_LEVEL === 'debug'
logger.debug(stringParameters(params))

if (params.__ow_method !== 'post') {
return errorResponse(405, 'Only POST allowed', logger)
}

// check for missing request input parameters and headers
const requiredParams = [
'SALESFORCE_TOKEN',
'SALESFORCE_REST_EVENTS_URI',
'SALESFORCE_REST_EVENTS_UPSERT_URI',
'payload',
]
const requiredHeaders = []
const errorMessage = checkMissingRequestInputs(params, requiredParams, requiredHeaders)
if (errorMessage) {
// return and log client errors
return errorResponse(400, errorMessage, logger)
}

const data = params.payload || {};
// create a Logger
logger = Core.Logger('main', { level: params.LOG_LEVEL || 'info' })
try {
// 'info' is the default level if not set
logger.info('Calling the main action')

const response = await createRequest('post', params.SALESFORCE_REST_EVENTS_URI, params.SALESFORCE_TOKEN, [], data)
if (response.status !== 201) {
// log parameters, only if params.LOG_LEVEL === 'debug'
logger.debug(stringParameters(params))

return await updateRequest('put', params.SALESFORCE_REST_EVENTS_UPSERT_URI, params.SALESFORCE_TOKEN, [], data, logger)
} else {
return {statusCode: 200, body: {values: data.Data}};
}
} catch (error) {
// log any server errors
logger.error(error)
// return with 500
return errorResponse(500, 'Catched internal server error', logger)
}
}
if (params.__ow_method !== 'post') {
return errorResponse(405, 'Only POST allowed', logger)
}

async function createRequest(method, url, token, queryParams, payload = false) {
const params = {
method: method,
headers: {
'Authorization': 'Bearer ' + token,
'Content-Type': 'application/json',
// check for missing request input parameters and headers
const requiredParams = [
'COSTCO_TOKEN',
'COSTCO_REST_URI',
'payload',
]
const requiredHeaders = []
const errorMessage = checkMissingRequestInputs(params, requiredParams, requiredHeaders)

if (errorMessage) {
// return and log client errors
return errorResponse(400, errorMessage, logger)
}
}

if (payload) {
params.body = JSON.stringify(payload)
}
const data = params.payload || {};
return await getPolicyData('get', params.COSTCO_REST_URI, params.COSTCO_TOKEN, data, logger);

let finalUrl = url;
if (Object.keys(queryParams).length > 0) {
finalUrl = url + '?' + new URLSearchParams(queryParams)
}

return await fetch(finalUrl , params);
} catch (error) {
// log any server errors
logger.error(error)
// return with 500
return errorResponse(500, 'Catched internal server error', logger)
}
}

async function updateRequest(method, url, token, queryParams, payload = false, logger) {
async function getPolicyData(method, endpoint, token, payload, logger) {
const params = {
method: method,
headers: {
'Authorization': 'Bearer ' + token,
'Content-Type': 'application/json',
}
}

if (payload) {
params.body = JSON.stringify({values: payload.Data})

url = url + 'EmailAddress:' + payload.ContactKey;
}


let finalUrl = url;
if (Object.keys(queryParams).length > 0) {
finalUrl = url + '?' + new URLSearchParams(queryParams)
}

const res = await fetch(finalUrl , params);
const policyId = payload.policyId ?? '';
const soqlQuery = `SELECT Id, Number__c, Type__c, Level__c, Status__c, Insurance_Policy__r.Status FROM Membership__c WHERE Insurance_Policy__c = '${policyId}'`;
const finalUrl = endpoint + "/services/data/v61.0/query/?q=";

const res = await fetch(finalUrl + encodeURIComponent(soqlQuery), params);
const body = await res.text();

try {
const jsonBody = JSON.parse(body);
return {
statusCode: 200,
body: {
"action": "updated",
"values": payload.Data,
},
body: jsonBody,
}
} catch (error) {
return errorResponse(500, 'Catched internal server error', logger)
Expand Down
20 changes: 10 additions & 10 deletions tools/appbuilder/app.config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -59,24 +59,24 @@ application:
annotions:
require-adobe-auth: false
final: true
pauls-authentication:
authentication-costco-figo:
function: actions/costco-figo-proxy/authentication.js
web: 'yes'
runtime: nodejs:20
inputs:
LOG_LEVEL: debug
SALESFORCE_CLIENT_ID: $SALESFORCE_CLIENT_ID
SALESFORCE_CLIENT_SECRET: $SALESFORCE_CLIENT_SECRET
SALESFORCE_AUTH_URI: $SALESFORCE_AUTH_URI
SALESFORCE_ACCOUNT_ID: $SALESFORCE_ACCOUNT_ID
SALESFORCE_SCOPES: "data_extensions_write data_extensions_read journeys_read list_and_subscribers_read"
pauls-service:
COSTCO_CLIENT_ID: $COSTCO_CLIENT_ID
COSTCO_CLIENT_SECRET: $COSTCO_CLIENT_SECRET
COSTCO_USERNAME: $COSTCO_USERNAME
COSTCO_PASSWORD: $COSTCO_PASSWORD
COSTCO_AUTH_URI: $COSTCO_AUTH_URI
service-costco-figo:
function: actions/costco-figo-proxy/service.js
web: 'yes'
runtime: nodejs:20
inputs:
LOG_LEVEL: debug

COSTCO_REST_URI: $COSTCO_REST_URI
sequences:
proxy-pethealth-services:
actions: authentication-pethealth, service-pethealth
Expand All @@ -87,6 +87,6 @@ application:
proxy-report-lost:
actions: report-lost, authentication-pethealth, service-pethealth
web: 'yes'
proxy-pauls-services:
actions: pauls-authentication, pauls-service
proxy-costco-figo-services:
actions: authentication-costco-figo, service-costco-figo
web: 'yes'

0 comments on commit 6221b74

Please sign in to comment.