Skip to content

Commit d51cad9

Browse files
author
Paulo Cabral
committed
Add js Auth example with PAT
1 parent 78bc3e8 commit d51cad9

File tree

7 files changed

+656
-0
lines changed

7 files changed

+656
-0
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Base Url endpoint
2+
BASE_URL='https://api-sandbox.uphold.com'
3+
4+
USERNAME ='my_registration_email@domain.com'
5+
PASSWORD = 'my_password_in_clear_text'
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
CLIENT CREDENTIAL PAT
2+
=====================
3+
4+
# Scenario
5+
**Ideal for scripts**, automated tools and command-line programs which remain under your control.
6+
7+
This example works if your account has 2FA active. You need to make use of the TOTP code provide by your chosen authenticator app (Google Auth, etc). Please look at `line 20` of `index.js` file.
8+
9+
- Creates a new PAT for API usage.
10+
- List all created PAT'S associated to this account
11+
12+
13+
## Stack
14+
- JS/ES6
15+
- `node` v13.14.0 +
16+
17+
## Setup
18+
- see the `package.json`
19+
- type: `npm install` or `yarn install`
20+
- Create a `.env` file based on the `.env.example` file and populate with the required DATA
21+
22+
23+
## RUN
24+
- node index.js
25+
26+
27+
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
/**
2+
* Dependencies.
3+
*/
4+
5+
import axios from "axios";
6+
import b64Pkg from "js-base64";
7+
import dotenv from "dotenv";
8+
import path from "path";
9+
10+
const { encode } = b64Pkg;
11+
dotenv.config({ path: path.resolve() + "/.env" });
12+
13+
/**
14+
* Get auth methods.
15+
*/
16+
17+
export async function getAuthenticationMethods() {
18+
// auth encoded with client ID and Client Secret
19+
// set get options for axios
20+
const auth = encode(process.env.USERNAME + ":" + process.env.PASSWORD);
21+
const url = `${process.env.BASE_URL}/v0/me/authentication_methods`;
22+
23+
const options = {
24+
method: "GET",
25+
headers: {
26+
Authorization: "Basic " + auth,
27+
"content-type": "application/json",
28+
},
29+
url,
30+
};
31+
32+
const data = axios(options)
33+
.then((response) => {
34+
return response.data;
35+
})
36+
.catch((error) => {
37+
error.response.data.errors
38+
? console.log(JSON.stringify(error.response.data.errors, null, 2))
39+
: console.log(JSON.stringify(error, null, 2));
40+
throw error;
41+
});
42+
43+
return data;
44+
}
45+
46+
/**
47+
* Create Pat Tokens.
48+
* The OTPToken is provided by your personal otp application (Google Authenticator, etc)
49+
*/
50+
51+
export async function createNewPAT(totp) {
52+
// auth encoded with username and password
53+
// set otp headers if passed!
54+
// set post options for axios
55+
const auth = encode(process.env.USERNAME + ":" + process.env.PASSWORD);
56+
57+
let headers = {
58+
"Authorization": "Basic " + auth,
59+
"content-type": "application/json",
60+
};
61+
62+
const otpHeaders = {
63+
"OTP-Method-Id": totp.OTPMethodId,
64+
"OTP-Token": totp.OTPToken,
65+
};
66+
67+
if (totp.OTPMethodId) {
68+
headers = { ...headers, ...otpHeaders };
69+
}
70+
71+
const url = `${process.env.BASE_URL}/v0/me/tokens`;
72+
const options = {
73+
method: "POST",
74+
headers,
75+
data: {
76+
description: "Put a Description Here",
77+
},
78+
url,
79+
};
80+
81+
const data = axios(options)
82+
.then((response) => {
83+
return response.data;
84+
})
85+
.catch((error) => {
86+
error.response.data.errors
87+
? console.log(JSON.stringify(error.response.data.errors, null, 2))
88+
: console.log(JSON.stringify(error, null, 2));
89+
throw error;
90+
});
91+
92+
return data;
93+
}
94+
95+
/**
96+
* Get Pat Tokens using an access token.
97+
*/
98+
99+
export async function getMyPATTokens(accessToken) {
100+
try {
101+
const r = await axios.get(`${process.env.BASE_URL}/v0/me/tokens`, {
102+
headers: {
103+
Authorization: `Bearer ${accessToken}`,
104+
},
105+
});
106+
return r.data;
107+
} catch (error) {
108+
console.log(JSON.stringify(error, null, 2));
109+
throw error;
110+
}
111+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/**
2+
* Dependencies.
3+
*/
4+
5+
import {
6+
createNewPAT,
7+
getAuthenticationMethods,
8+
getMyPATTokens,
9+
} from "./cc-pat.js";
10+
11+
(async () => {
12+
// Get Authentication tokens
13+
const authMethods = await getAuthenticationMethods();
14+
15+
let totp = {
16+
OTPMethodId: "",
17+
OTPToken: "783631", // WARNING!!! IF YOUR ACCOUNT HAS 2FA ON, PLEASE INSERT HERE THE OTP TOKEN PROVIDED BY YOUR APP (google authenticator, etc)!
18+
};
19+
20+
// Try to determine if we have 2FA active!
21+
const totpCheck =
22+
authMethods != null ? authMethods.find((x) => x.type === "totp") : null;
23+
if (totpCheck) {
24+
totp.OTPMethodId = totpCheck.id;
25+
}
26+
27+
const newPAT = await createNewPAT(totp);
28+
29+
if (newPAT.accessToken) {
30+
console.log("New Private Access Token Created with success");
31+
console.debug(newPAT.accessToken);
32+
33+
// Use the access token to list all PAT Tokens Created!
34+
console.log("List PAT Tokens");
35+
console.log(await getMyPATTokens(newPAT.accessToken));
36+
}
37+
})();

0 commit comments

Comments
 (0)