Skip to content

Commit ec7be0f

Browse files
committed
working sign in, sign out, list pastes
1 parent aef627a commit ec7be0f

File tree

8 files changed

+2567
-9
lines changed

8 files changed

+2567
-9
lines changed

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,3 +102,9 @@ dist
102102

103103
# TernJS port file
104104
.tern-port
105+
106+
# IDE
107+
.vscode/
108+
109+
# other stuff
110+
.pasty.json

README.md

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,27 +13,27 @@ pasty is a cli for pastebin.com. With it you can:
1313

1414
first, login:
1515

16-
```shell
16+
```
1717
$ pasty login <username>
1818
```
1919

2020
then, create a paste:
2121

22-
```shell
23-
$ pasty create -s "hello world!"
22+
```
23+
$ pasty create -s 'hello world!'
2424
```
2525

2626
alternativly, you can upload a file:
2727

28-
```shell
28+
```
2929
$ pasty create -f hello_world.txt
3030
```
3131

3232
## other commands
3333

3434
list all your pastes:
3535

36-
```shell
36+
```
3737
$ pasty list
3838
```
3939

@@ -45,23 +45,29 @@ $ pasty delete <unique id>
4545

4646
get a paste's content:
4747

48-
```shell
48+
```
4949
$ pasty get <unique id>
5050
```
5151

5252
get info about signed in user:
5353

54-
```shell
54+
```
5555
$ pasty user-info
5656
```
5757

58+
logout:
59+
60+
```
61+
$ pasty logout
62+
```
63+
5864
# more options
5965

6066
you can customize your newly created paste:
6167

62-
- syntax highlighting (default: none)
68+
- syntax highlighting (default: text)
6369
- [supported hightlighting formats](https://pastebin.com/faq#10)
64-
- expiry date (default: none)
70+
- expiry date (default: never)
6571
- never (N)
6672
- 10 minutes (10M)
6773
- 1 hour (1H)

lib/api-functions.js

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
import inquirer from 'inquirer';
2+
import { tokenGuard } from './functions.js';
3+
import fetch from 'node-fetch';
4+
import { LOGIN_LINK, TABLE_HEADERS } from './constant.js';
5+
import { rmSync, writeFileSync } from 'fs';
6+
import { homedir } from 'os';
7+
import { JSDOM } from 'jsdom';
8+
import { table } from 'table';
9+
10+
export async function loginUser(argv, apiToken) {
11+
if (tokenGuard(apiToken)) {
12+
console.log(
13+
'Please provide your pastebin.com API token in the ~/.pasty.api file.'
14+
);
15+
process.exit(1);
16+
}
17+
18+
const username = argv.username;
19+
const password = (
20+
await inquirer.prompt([
21+
{
22+
type: 'password',
23+
message: 'enter your password:',
24+
name: 'password',
25+
mask: '*',
26+
},
27+
])
28+
).password;
29+
30+
const response = await fetch(LOGIN_LINK, {
31+
body: `api_dev_key=${apiToken}&api_user_name=${username}&api_user_password=${password}`,
32+
headers: {
33+
'Content-Type': 'application/x-www-form-urlencoded',
34+
},
35+
method: 'POST',
36+
});
37+
38+
if (response.status === 200) {
39+
const userToken = await response.text();
40+
writeFileSync(`${homedir()}/.pasty.user`, userToken, 'utf-8');
41+
console.log(`Success! You're now logged in as ${username}`);
42+
} else {
43+
console.log(await response.text());
44+
process.exit(1);
45+
}
46+
}
47+
48+
export async function listPastes(argv, apiToken, userToken) {
49+
if (tokenGuard(apiToken)) {
50+
console.log(
51+
'Please provide your pastebin.com API token in the ~/.pasty.api file.'
52+
);
53+
process.exit(1);
54+
}
55+
56+
if (tokenGuard(userToken)) {
57+
console.log('Please login first via pasty login <username>');
58+
process.exit(1);
59+
}
60+
61+
const amount = argv.amount;
62+
63+
const response = await fetch('https://pastebin.com/api/api_post.php', {
64+
body: `api_dev_key=${apiToken}&api_user_key=${userToken}&api_option=list&api_results_limit=${amount}`,
65+
headers: {
66+
'Content-Type': 'application/x-www-form-urlencoded',
67+
},
68+
method: 'POST',
69+
});
70+
const data = await response.text();
71+
72+
if (response.status === 200) {
73+
const tableData = [];
74+
tableData.push(TABLE_HEADERS);
75+
76+
const xmlResponse = new JSDOM(data);
77+
78+
xmlResponse.window.document.querySelectorAll('paste').forEach((paste) => {
79+
const pasteRow = [];
80+
81+
pasteRow.push(paste.querySelector('paste_key').textContent);
82+
pasteRow.push(paste.querySelector('paste_title').textContent);
83+
pasteRow.push(paste.querySelector('paste_private').textContent);
84+
pasteRow.push(paste.querySelector('paste_expire_date').textContent);
85+
pasteRow.push(paste.querySelector('paste_format_short').textContent);
86+
87+
tableData.push(pasteRow);
88+
});
89+
90+
console.log(table(tableData));
91+
} else {
92+
console.log('Could not get pastes: ', data);
93+
}
94+
}
95+
96+
export function logout() {
97+
try {
98+
rmSync(`${homedir()}/.pasty.user`);
99+
console.log('Success! Logged you out.');
100+
} catch (e) {
101+
console.log("You're currently not logged in");
102+
}
103+
}

lib/constant.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
export const LOGIN_LINK = 'https://pastebin.com/api/api_login.php';
2+
3+
export const TABLE_HEADERS = [
4+
'paste id',
5+
'paste name',
6+
'paste visibilty',
7+
'paste expiry',
8+
'paste syntax highlighting',
9+
];

lib/functions.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export function tokenGuard(token) {
2+
return token === '' || token === undefined || token === null;
3+
}

lib/main.js

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import yargs from 'yargs';
2+
import { hideBin } from 'yargs/helpers';
3+
import { readFileSync } from 'fs';
4+
import { homedir } from 'os';
5+
import { listPastes, loginUser, logout } from './api-functions.js';
6+
7+
let userToken;
8+
let apiToken;
9+
10+
try {
11+
apiToken = readFileSync(`${homedir()}/.pasty.api`, 'utf-8').trim();
12+
} catch (e) {
13+
console.log(
14+
"It seems like you don't have a ~/.pasty.api file. Please create it and provide your API token."
15+
);
16+
process.exit(1);
17+
}
18+
try {
19+
userToken = readFileSync(`${homedir()}/.pasty.user`, 'utf-8').trim();
20+
} catch (e) {
21+
// if file does not exist, user is not logged in yet. this is fine
22+
}
23+
24+
yargs(hideBin(process.argv))
25+
.command(
26+
'login <username>',
27+
'logs you in',
28+
(yargs) => {
29+
return yargs.positional('username', {
30+
describe: 'your username',
31+
});
32+
},
33+
(argv) => {
34+
loginUser(argv, apiToken);
35+
}
36+
)
37+
.command(
38+
'list [amount]',
39+
'list your pastes',
40+
(yargs) => {
41+
return yargs.positional('amount', {
42+
default: 20,
43+
describe: 'the amount of pastes to be displayed',
44+
});
45+
},
46+
(argv) => {
47+
listPastes(argv, apiToken, userToken);
48+
}
49+
)
50+
.command(
51+
'logout',
52+
'logs you out',
53+
() => {},
54+
() => {
55+
logout();
56+
}
57+
)
58+
.demandCommand(1)
59+
.parse();

0 commit comments

Comments
 (0)