keybase-proofs 2.3.26 → 2.3.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/lib/constants.js +2 -1
- package/lib/scrapers/base.js +18 -8
- package/lib/scrapers/dns.js +18 -6
- package/lib/scrapers/twitter.js +63 -134
- package/package.json +1 -1
- package/src/constants.iced +1 -0
- package/src/scrapers/base.iced +17 -5
- package/src/scrapers/dns.iced +13 -3
- package/src/scrapers/twitter.iced +29 -70
- package/SIGNED.md +0 -131
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
## 2.3.29 (2024-07-22)
|
|
2
|
+
|
|
3
|
+
- Fix Twitter scraper to handle empty result list case.
|
|
4
|
+
|
|
5
|
+
## 2.3.28 (2024-07-19)
|
|
6
|
+
|
|
7
|
+
- Use version 2 API for X (formerly known as Twitter) hunting.
|
|
8
|
+
|
|
9
|
+
## 2.3.27 (2024-07-18)
|
|
10
|
+
|
|
11
|
+
- Fix error handling when an invalid unicode domain is passed to DnsScraper.
|
|
12
|
+
|
|
1
13
|
## 2.3.26 (2024-06-17)
|
|
2
14
|
|
|
3
15
|
- Use oauth API for reddit scraping.
|
package/lib/constants.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Generated by IcedCoffeeScript 108.0.
|
|
1
|
+
// Generated by IcedCoffeeScript 108.0.11
|
|
2
2
|
(function() {
|
|
3
3
|
var constants, d, k, v, _ref;
|
|
4
4
|
|
|
@@ -172,6 +172,7 @@
|
|
|
172
172
|
HTTP_400: 240,
|
|
173
173
|
HTTP_OTHER: 260,
|
|
174
174
|
EMPTY_JSON: 270,
|
|
175
|
+
INVALID_JSON: 271,
|
|
175
176
|
DELETED: 301,
|
|
176
177
|
SERVICE_DEAD: 302,
|
|
177
178
|
BAD_SIGNATURE: 303
|
package/lib/scrapers/base.js
CHANGED
|
@@ -143,6 +143,15 @@
|
|
|
143
143
|
return b64find(raw, ptc_buf);
|
|
144
144
|
};
|
|
145
145
|
|
|
146
|
+
BaseScraper.prototype._get_rate_limit_header = function(headers, name) {
|
|
147
|
+
var v;
|
|
148
|
+
if ((v = parse_int_or_undefined(headers.get("X-RateLimit-" + name))) || (v = parse_int_or_undefined(headers.get("X-Rate-Limit-" + name)))) {
|
|
149
|
+
return v;
|
|
150
|
+
} else {
|
|
151
|
+
return void 0;
|
|
152
|
+
}
|
|
153
|
+
};
|
|
154
|
+
|
|
146
155
|
BaseScraper.prototype._get_url_body = function(opts, cb) {
|
|
147
156
|
var body, err, f, rc, response, rl_limit, rl_remaining, rl_reset, ___iced_passed_deferral, __iced_deferrals, __iced_k, _base;
|
|
148
157
|
__iced_k = __iced_k_noop;
|
|
@@ -172,7 +181,7 @@
|
|
|
172
181
|
return response = arguments[1];
|
|
173
182
|
};
|
|
174
183
|
})(),
|
|
175
|
-
lineno:
|
|
184
|
+
lineno: 96
|
|
176
185
|
}));
|
|
177
186
|
__iced_deferrals._fulfill();
|
|
178
187
|
});
|
|
@@ -180,9 +189,9 @@
|
|
|
180
189
|
return function() {
|
|
181
190
|
var _base1, _ref;
|
|
182
191
|
if (opts.log_ratelimit && (typeof response !== "undefined" && response !== null)) {
|
|
183
|
-
rl_limit =
|
|
184
|
-
rl_remaining =
|
|
185
|
-
rl_reset =
|
|
192
|
+
rl_limit = _this._get_rate_limit_header(response.headers, 'Limit');
|
|
193
|
+
rl_remaining = _this._get_rate_limit_header(response.headers, 'Remaining');
|
|
194
|
+
rl_reset = _this._get_rate_limit_header(response.headers, 'Reset');
|
|
186
195
|
if (rl_limit != null) {
|
|
187
196
|
_this.log("| ratelimit info limit=" + rl_limit + " remaining=" + rl_remaining + " reset=" + rl_reset);
|
|
188
197
|
}
|
|
@@ -190,7 +199,8 @@
|
|
|
190
199
|
_base1.ratelimit_inform({
|
|
191
200
|
limit: rl_limit,
|
|
192
201
|
remaining: rl_remaining,
|
|
193
|
-
reset: rl_reset
|
|
202
|
+
reset: rl_reset,
|
|
203
|
+
endpoint_name: opts.endpoint_name
|
|
194
204
|
});
|
|
195
205
|
}
|
|
196
206
|
}
|
|
@@ -213,7 +223,7 @@
|
|
|
213
223
|
return body = arguments[1];
|
|
214
224
|
};
|
|
215
225
|
})(),
|
|
216
|
-
lineno:
|
|
226
|
+
lineno: 122
|
|
217
227
|
}));
|
|
218
228
|
__iced_deferrals._fulfill();
|
|
219
229
|
})(function() {
|
|
@@ -273,7 +283,7 @@
|
|
|
273
283
|
funcname: "BaseBearerToken.get"
|
|
274
284
|
});
|
|
275
285
|
_this._lock.acquire(__iced_deferrals.defer({
|
|
276
|
-
lineno:
|
|
286
|
+
lineno: 160
|
|
277
287
|
}));
|
|
278
288
|
__iced_deferrals._fulfill();
|
|
279
289
|
});
|
|
@@ -316,7 +326,7 @@
|
|
|
316
326
|
return body = arguments[2];
|
|
317
327
|
};
|
|
318
328
|
})(),
|
|
319
|
-
lineno:
|
|
329
|
+
lineno: 185
|
|
320
330
|
}));
|
|
321
331
|
__iced_deferrals._fulfill();
|
|
322
332
|
})(function() {
|
package/lib/scrapers/dns.js
CHANGED
|
@@ -151,7 +151,7 @@
|
|
|
151
151
|
(function(__iced_k) {
|
|
152
152
|
__iced_deferrals = new iced.Deferrals(__iced_k, {
|
|
153
153
|
parent: ___iced_passed_deferral,
|
|
154
|
-
filename: "/Users/
|
|
154
|
+
filename: "/Users/michal/SourceCode/keybase/go/src/github.com/keybase/server_test_progs/proofs/src/scrapers/dns.iced",
|
|
155
155
|
funcname: "DnsScraper.check_status"
|
|
156
156
|
});
|
|
157
157
|
_this._check_status({
|
|
@@ -191,28 +191,40 @@ _break()
|
|
|
191
191
|
})(this));
|
|
192
192
|
};
|
|
193
193
|
|
|
194
|
+
DnsScraper.prototype._resolve_txt = function(domain, cb) {
|
|
195
|
+
var dnslib, err;
|
|
196
|
+
dnslib = this.libs.dns || dns;
|
|
197
|
+
try {
|
|
198
|
+
return dnslib.resolveTxt(domain, function(err, records) {
|
|
199
|
+
return cb(err, records);
|
|
200
|
+
});
|
|
201
|
+
} catch (_error) {
|
|
202
|
+
err = _error;
|
|
203
|
+
return cb(err);
|
|
204
|
+
}
|
|
205
|
+
};
|
|
206
|
+
|
|
194
207
|
DnsScraper.prototype._check_status = function(_arg, cb) {
|
|
195
|
-
var
|
|
208
|
+
var domain, err, proof_text_check, rc, records, ___iced_passed_deferral, __iced_deferrals, __iced_k;
|
|
196
209
|
__iced_k = __iced_k_noop;
|
|
197
210
|
___iced_passed_deferral = iced.findDeferral(arguments);
|
|
198
211
|
domain = _arg.domain, proof_text_check = _arg.proof_text_check;
|
|
199
212
|
this.log("+ DNS check for " + domain);
|
|
200
|
-
dnslib = this.libs.dns || dns;
|
|
201
213
|
(function(_this) {
|
|
202
214
|
return (function(__iced_k) {
|
|
203
215
|
__iced_deferrals = new iced.Deferrals(__iced_k, {
|
|
204
216
|
parent: ___iced_passed_deferral,
|
|
205
|
-
filename: "/Users/
|
|
217
|
+
filename: "/Users/michal/SourceCode/keybase/go/src/github.com/keybase/server_test_progs/proofs/src/scrapers/dns.iced",
|
|
206
218
|
funcname: "DnsScraper._check_status"
|
|
207
219
|
});
|
|
208
|
-
|
|
220
|
+
_this._resolve_txt(domain, __iced_deferrals.defer({
|
|
209
221
|
assign_fn: (function() {
|
|
210
222
|
return function() {
|
|
211
223
|
err = arguments[0];
|
|
212
224
|
return records = arguments[1];
|
|
213
225
|
};
|
|
214
226
|
})(),
|
|
215
|
-
lineno:
|
|
227
|
+
lineno: 115
|
|
216
228
|
}));
|
|
217
229
|
__iced_deferrals._fulfill();
|
|
218
230
|
});
|
package/lib/scrapers/twitter.js
CHANGED
|
@@ -1,20 +1,18 @@
|
|
|
1
|
-
// Generated by IcedCoffeeScript 108.0.
|
|
1
|
+
// Generated by IcedCoffeeScript 108.0.11
|
|
2
2
|
(function() {
|
|
3
|
-
var
|
|
3
|
+
var BaseBearerToken, BaseScraper, TwitterBearerToken, TwitterScraper, bearer_token, constants, decode_sig, iced, make_ids, schema, sncmp, urlmod, v_codes, ws_normalize, __iced_k, __iced_k_noop, _bearer_token, _ref,
|
|
4
4
|
__hasProp = {}.hasOwnProperty,
|
|
5
5
|
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
|
|
6
6
|
|
|
7
7
|
iced = require('iced-runtime');
|
|
8
8
|
__iced_k = __iced_k_noop = function() {};
|
|
9
9
|
|
|
10
|
-
_ref = require('./base'), sncmp = _ref.sncmp, BaseScraper = _ref.BaseScraper;
|
|
10
|
+
_ref = require('./base'), sncmp = _ref.sncmp, BaseScraper = _ref.BaseScraper, BaseBearerToken = _ref.BaseBearerToken;
|
|
11
11
|
|
|
12
12
|
make_ids = require('../base').make_ids;
|
|
13
13
|
|
|
14
14
|
constants = require('../constants').constants;
|
|
15
15
|
|
|
16
|
-
Lock = require('../util').Lock;
|
|
17
|
-
|
|
18
16
|
v_codes = constants.v_codes;
|
|
19
17
|
|
|
20
18
|
decode_sig = require('kbpgp').ukm.decode_sig;
|
|
@@ -35,108 +33,22 @@
|
|
|
35
33
|
return v.join(' ');
|
|
36
34
|
};
|
|
37
35
|
|
|
38
|
-
|
|
39
|
-
|
|
36
|
+
TwitterBearerToken = (function(_super) {
|
|
37
|
+
__extends(TwitterBearerToken, _super);
|
|
38
|
+
|
|
39
|
+
function TwitterBearerToken(_arg) {
|
|
40
40
|
this.base = _arg.base;
|
|
41
|
-
this
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
41
|
+
TwitterBearerToken.__super__.constructor.call(this, {
|
|
42
|
+
name: "Twitter",
|
|
43
|
+
base: this.base,
|
|
44
|
+
access_token_url: "https://api.twitter.com/oauth2/token",
|
|
45
|
+
scope: ['history', 'read']
|
|
46
|
+
});
|
|
45
47
|
}
|
|
46
48
|
|
|
47
|
-
|
|
48
|
-
var body, cred, e, err, now, opts, rc, req, res, tok, ___iced_passed_deferral, __iced_deferrals, __iced_k;
|
|
49
|
-
__iced_k = __iced_k_noop;
|
|
50
|
-
___iced_passed_deferral = iced.findDeferral(arguments);
|
|
51
|
-
(function(_this) {
|
|
52
|
-
return (function(__iced_k) {
|
|
53
|
-
__iced_deferrals = new iced.Deferrals(__iced_k, {
|
|
54
|
-
parent: ___iced_passed_deferral,
|
|
55
|
-
filename: "/home/zapu/Projects/KB/proofs/src/scrapers/twitter.iced",
|
|
56
|
-
funcname: "BearerToken.get"
|
|
57
|
-
});
|
|
58
|
-
_this._lock.acquire(__iced_deferrals.defer({
|
|
59
|
-
lineno: 32
|
|
60
|
-
}));
|
|
61
|
-
__iced_deferrals._fulfill();
|
|
62
|
-
});
|
|
63
|
-
})(this)((function(_this) {
|
|
64
|
-
return function() {
|
|
65
|
-
err = null;
|
|
66
|
-
now = Math.floor(Date.now() / 1000);
|
|
67
|
-
(function(__iced_k) {
|
|
68
|
-
if (((res = _this._tok) == null) || (now - _this._created > _this.auth.lifespan)) {
|
|
69
|
-
_this.base.log("+ Request for bearer token");
|
|
70
|
-
cred = (Buffer.from([_this.auth.key, _this.auth.secret].join(":"))).toString('base64');
|
|
71
|
-
req = 'grant_type=client_credentials';
|
|
72
|
-
opts = {
|
|
73
|
-
url: "https://api.twitter.com/oauth2/token",
|
|
74
|
-
headers: {
|
|
75
|
-
Authorization: "Basic " + cred,
|
|
76
|
-
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
|
|
77
|
-
'Content-Length': req.length
|
|
78
|
-
},
|
|
79
|
-
method: "post",
|
|
80
|
-
body: req
|
|
81
|
-
};
|
|
82
|
-
(function(__iced_k) {
|
|
83
|
-
__iced_deferrals = new iced.Deferrals(__iced_k, {
|
|
84
|
-
parent: ___iced_passed_deferral,
|
|
85
|
-
filename: "/home/zapu/Projects/KB/proofs/src/scrapers/twitter.iced",
|
|
86
|
-
funcname: "BearerToken.get"
|
|
87
|
-
});
|
|
88
|
-
_this.base._get_url_body(opts, __iced_deferrals.defer({
|
|
89
|
-
assign_fn: (function() {
|
|
90
|
-
return function() {
|
|
91
|
-
err = arguments[0];
|
|
92
|
-
rc = arguments[1];
|
|
93
|
-
return body = arguments[2];
|
|
94
|
-
};
|
|
95
|
-
})(),
|
|
96
|
-
lineno: 52
|
|
97
|
-
}));
|
|
98
|
-
__iced_deferrals._fulfill();
|
|
99
|
-
})(function() {
|
|
100
|
-
if (err != null) {
|
|
101
|
-
_this.base.logl('error', "In getting bearer_token: " + err.message);
|
|
102
|
-
} else if (rc !== v_codes.OK) {
|
|
103
|
-
_this.base.logl('error', "HTTP error in getting bearer token: " + rc);
|
|
104
|
-
err = new Error("HTTP error: " + rc);
|
|
105
|
-
} else {
|
|
106
|
-
try {
|
|
107
|
-
body = JSON.parse(body);
|
|
108
|
-
} catch (_error) {
|
|
109
|
-
e = _error;
|
|
110
|
-
_this.base.logl('warn', "Could not parse JSON reply: " + e);
|
|
111
|
-
err = e;
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
if (err != null) {
|
|
115
|
-
|
|
116
|
-
} else if ((tok = body.access_token) == null) {
|
|
117
|
-
_this.base.logl('warn', "No access token found in reply");
|
|
118
|
-
err = new Error("Twitter error: no access token");
|
|
119
|
-
} else {
|
|
120
|
-
_this._tok = tok;
|
|
121
|
-
_this._created = Math.floor(Date.now() / 1000);
|
|
122
|
-
res = _this._tok;
|
|
123
|
-
}
|
|
124
|
-
return __iced_k(_this.base.log("- Request for bearer token -> " + err));
|
|
125
|
-
});
|
|
126
|
-
} else {
|
|
127
|
-
return __iced_k();
|
|
128
|
-
}
|
|
129
|
-
})(function() {
|
|
130
|
-
_this._lock.release();
|
|
131
|
-
return cb(err, res);
|
|
132
|
-
});
|
|
133
|
-
};
|
|
134
|
-
})(this));
|
|
135
|
-
};
|
|
136
|
-
|
|
137
|
-
return BearerToken;
|
|
49
|
+
return TwitterBearerToken;
|
|
138
50
|
|
|
139
|
-
})();
|
|
51
|
+
})(BaseBearerToken);
|
|
140
52
|
|
|
141
53
|
_bearer_token = null;
|
|
142
54
|
|
|
@@ -144,7 +56,7 @@
|
|
|
144
56
|
var base;
|
|
145
57
|
base = _arg.base;
|
|
146
58
|
if (!_bearer_token) {
|
|
147
|
-
_bearer_token = new
|
|
59
|
+
_bearer_token = new TwitterBearerToken({
|
|
148
60
|
base: base
|
|
149
61
|
});
|
|
150
62
|
}
|
|
@@ -152,8 +64,12 @@
|
|
|
152
64
|
};
|
|
153
65
|
|
|
154
66
|
exports.TwitterScraper = TwitterScraper = (function(_super) {
|
|
67
|
+
var username_regexp;
|
|
68
|
+
|
|
155
69
|
__extends(TwitterScraper, _super);
|
|
156
70
|
|
|
71
|
+
username_regexp = /^[a-z0-9_-]{2,15}$/;
|
|
72
|
+
|
|
157
73
|
function TwitterScraper(opts) {
|
|
158
74
|
this.auth = opts.auth;
|
|
159
75
|
TwitterScraper.__super__.constructor.call(this, opts);
|
|
@@ -164,13 +80,15 @@
|
|
|
164
80
|
return new Error("Bad args to Twitter proof: no username given");
|
|
165
81
|
} else if (!(args.name != null) || (args.name !== 'twitter')) {
|
|
166
82
|
return new Error("Bad args to Twitter proof: type is " + args.name);
|
|
83
|
+
} else if (!args.username.match(username_regexp)) {
|
|
84
|
+
return new Error("Invalid username passed to Twitter proof");
|
|
167
85
|
} else {
|
|
168
86
|
return null;
|
|
169
87
|
}
|
|
170
88
|
};
|
|
171
89
|
|
|
172
90
|
TwitterScraper.prototype.hunt2 = function(_arg, cb) {
|
|
173
|
-
var api_url, err, human_url, i,
|
|
91
|
+
var api_url, endpoint_name, err, human_url, i, id, json, name, out, proof_text_check, rc, remote_id, text, u, username, ___iced_passed_deferral, __iced_deferrals, __iced_k;
|
|
174
92
|
__iced_k = __iced_k_noop;
|
|
175
93
|
___iced_passed_deferral = iced.findDeferral(arguments);
|
|
176
94
|
username = _arg.username, name = _arg.name, proof_text_check = _arg.proof_text_check;
|
|
@@ -182,24 +100,25 @@
|
|
|
182
100
|
})) != null) {
|
|
183
101
|
return cb(err, out);
|
|
184
102
|
}
|
|
103
|
+
endpoint_name = "/2/tweets/search/recent";
|
|
185
104
|
u = urlmod.format({
|
|
186
105
|
host: "api.twitter.com",
|
|
187
106
|
protocol: "https:",
|
|
188
|
-
pathname:
|
|
107
|
+
pathname: endpoint_name,
|
|
189
108
|
query: {
|
|
190
|
-
|
|
191
|
-
screen_name: username
|
|
109
|
+
query: "\"Verifying myself\" \"Keybase.io\" from:" + username
|
|
192
110
|
}
|
|
193
111
|
});
|
|
194
112
|
(function(_this) {
|
|
195
113
|
return (function(__iced_k) {
|
|
196
114
|
__iced_deferrals = new iced.Deferrals(__iced_k, {
|
|
197
115
|
parent: ___iced_passed_deferral,
|
|
198
|
-
filename: "/
|
|
116
|
+
filename: "/Users/michal/SourceCode/keybase/go/src/github.com/keybase/server_test_progs/proofs/src/scrapers/twitter.iced",
|
|
199
117
|
funcname: "TwitterScraper.hunt2"
|
|
200
118
|
});
|
|
201
119
|
_this._get_body_api({
|
|
202
|
-
url: u
|
|
120
|
+
url: u,
|
|
121
|
+
endpoint_name: endpoint_name
|
|
203
122
|
}, __iced_deferrals.defer({
|
|
204
123
|
assign_fn: (function() {
|
|
205
124
|
return function() {
|
|
@@ -208,28 +127,36 @@
|
|
|
208
127
|
return json = arguments[2];
|
|
209
128
|
};
|
|
210
129
|
})(),
|
|
211
|
-
lineno:
|
|
130
|
+
lineno: 73
|
|
212
131
|
}));
|
|
213
132
|
__iced_deferrals._fulfill();
|
|
214
133
|
});
|
|
215
134
|
})(this)((function(_this) {
|
|
216
135
|
return function() {
|
|
217
|
-
var _i, _len, _ref1;
|
|
136
|
+
var _i, _len, _ref1, _ref2, _ref3;
|
|
218
137
|
_this.log("| search index " + u + " -> " + rc);
|
|
219
138
|
if (rc !== v_codes.OK) {
|
|
220
139
|
|
|
221
140
|
} else if ((typeof json === "undefined" || json === null) || (json.length === 0)) {
|
|
222
141
|
rc = v_codes.EMPTY_JSON;
|
|
142
|
+
} else if (json.data == null) {
|
|
143
|
+
if (((_ref1 = json.meta) != null ? _ref1.result_count : void 0) === 0) {
|
|
144
|
+
rc = v_codes.NOT_FOUND;
|
|
145
|
+
} else {
|
|
146
|
+
rc = v_codes.INVALID_JSON;
|
|
147
|
+
}
|
|
223
148
|
} else {
|
|
224
|
-
|
|
225
|
-
|
|
149
|
+
rc = v_codes.NOT_FOUND;
|
|
150
|
+
_ref2 = json.data;
|
|
151
|
+
for (i = _i = 0, _len = _ref2.length; _i < _len; i = ++_i) {
|
|
152
|
+
_ref3 = _ref2[i], text = _ref3.text, id = _ref3.id;
|
|
226
153
|
if ((_this.find_sig_in_tweet({
|
|
227
154
|
inside: text,
|
|
228
155
|
proof_text_check: proof_text_check
|
|
229
156
|
})) === v_codes.OK) {
|
|
230
157
|
_this.log("| found valid tweet in stream @ " + i);
|
|
231
158
|
rc = v_codes.OK;
|
|
232
|
-
remote_id =
|
|
159
|
+
remote_id = id;
|
|
233
160
|
api_url = human_url = _this._id_to_url(username, remote_id);
|
|
234
161
|
out = {
|
|
235
162
|
remote_id: remote_id,
|
|
@@ -295,7 +222,7 @@
|
|
|
295
222
|
(function(__iced_k) {
|
|
296
223
|
__iced_deferrals = new iced.Deferrals(__iced_k, {
|
|
297
224
|
parent: ___iced_passed_deferral,
|
|
298
|
-
filename: "/
|
|
225
|
+
filename: "/Users/michal/SourceCode/keybase/go/src/github.com/keybase/server_test_progs/proofs/src/scrapers/twitter.iced",
|
|
299
226
|
funcname: "TwitterScraper.users_lookup"
|
|
300
227
|
});
|
|
301
228
|
_this._get_body_api({
|
|
@@ -308,7 +235,7 @@
|
|
|
308
235
|
return json = arguments[2];
|
|
309
236
|
};
|
|
310
237
|
})(),
|
|
311
|
-
lineno:
|
|
238
|
+
lineno: 129
|
|
312
239
|
}));
|
|
313
240
|
__iced_deferrals._fulfill();
|
|
314
241
|
})(function() {
|
|
@@ -338,11 +265,11 @@
|
|
|
338
265
|
(function(__iced_k) {
|
|
339
266
|
__iced_deferrals = new iced.Deferrals(__iced_k, {
|
|
340
267
|
parent: ___iced_passed_deferral,
|
|
341
|
-
filename: "/
|
|
268
|
+
filename: "/Users/michal/SourceCode/keybase/go/src/github.com/keybase/server_test_progs/proofs/src/scrapers/twitter.iced",
|
|
342
269
|
funcname: "TwitterScraper.users_lookup"
|
|
343
270
|
});
|
|
344
271
|
setTimeout(__iced_deferrals.defer({
|
|
345
|
-
lineno:
|
|
272
|
+
lineno: 143
|
|
346
273
|
}), cursor_wait);
|
|
347
274
|
__iced_deferrals._fulfill();
|
|
348
275
|
})(__iced_k);
|
|
@@ -424,7 +351,7 @@
|
|
|
424
351
|
(function(__iced_k) {
|
|
425
352
|
__iced_deferrals = new iced.Deferrals(__iced_k, {
|
|
426
353
|
parent: ___iced_passed_deferral,
|
|
427
|
-
filename: "/
|
|
354
|
+
filename: "/Users/michal/SourceCode/keybase/go/src/github.com/keybase/server_test_progs/proofs/src/scrapers/twitter.iced",
|
|
428
355
|
funcname: "TwitterScraper.get_follower_ids"
|
|
429
356
|
});
|
|
430
357
|
_this._get_body_api({
|
|
@@ -437,7 +364,7 @@
|
|
|
437
364
|
return json = arguments[2];
|
|
438
365
|
};
|
|
439
366
|
})(),
|
|
440
|
-
lineno:
|
|
367
|
+
lineno: 181
|
|
441
368
|
}));
|
|
442
369
|
__iced_deferrals._fulfill();
|
|
443
370
|
})(function() {
|
|
@@ -470,11 +397,11 @@
|
|
|
470
397
|
(function(__iced_k) {
|
|
471
398
|
__iced_deferrals = new iced.Deferrals(__iced_k, {
|
|
472
399
|
parent: ___iced_passed_deferral,
|
|
473
|
-
filename: "/
|
|
400
|
+
filename: "/Users/michal/SourceCode/keybase/go/src/github.com/keybase/server_test_progs/proofs/src/scrapers/twitter.iced",
|
|
474
401
|
funcname: "TwitterScraper.get_follower_ids"
|
|
475
402
|
});
|
|
476
403
|
setTimeout(__iced_deferrals.defer({
|
|
477
|
-
lineno:
|
|
404
|
+
lineno: 197
|
|
478
405
|
}), cursor_wait);
|
|
479
406
|
__iced_deferrals._fulfill();
|
|
480
407
|
})(__iced_k);
|
|
@@ -576,7 +503,7 @@
|
|
|
576
503
|
return (function(__iced_k) {
|
|
577
504
|
__iced_deferrals = new iced.Deferrals(__iced_k, {
|
|
578
505
|
parent: ___iced_passed_deferral,
|
|
579
|
-
filename: "/
|
|
506
|
+
filename: "/Users/michal/SourceCode/keybase/go/src/github.com/keybase/server_test_progs/proofs/src/scrapers/twitter.iced",
|
|
580
507
|
funcname: "TwitterScraper.check_status"
|
|
581
508
|
});
|
|
582
509
|
_this._get_url_body({
|
|
@@ -590,7 +517,7 @@
|
|
|
590
517
|
return body_obj = arguments[2];
|
|
591
518
|
};
|
|
592
519
|
})(),
|
|
593
|
-
lineno:
|
|
520
|
+
lineno: 288
|
|
594
521
|
}));
|
|
595
522
|
__iced_deferrals._fulfill();
|
|
596
523
|
});
|
|
@@ -663,7 +590,7 @@
|
|
|
663
590
|
return (function(__iced_k) {
|
|
664
591
|
__iced_deferrals = new iced.Deferrals(__iced_k, {
|
|
665
592
|
parent: ___iced_passed_deferral,
|
|
666
|
-
filename: "/
|
|
593
|
+
filename: "/Users/michal/SourceCode/keybase/go/src/github.com/keybase/server_test_progs/proofs/src/scrapers/twitter.iced",
|
|
667
594
|
funcname: "TwitterScraper._get_bearer_token"
|
|
668
595
|
});
|
|
669
596
|
bt.get(__iced_deferrals.defer({
|
|
@@ -673,7 +600,7 @@
|
|
|
673
600
|
return tok = arguments[1];
|
|
674
601
|
};
|
|
675
602
|
})(),
|
|
676
|
-
lineno:
|
|
603
|
+
lineno: 349
|
|
677
604
|
}));
|
|
678
605
|
__iced_deferrals._fulfill();
|
|
679
606
|
});
|
|
@@ -686,16 +613,16 @@
|
|
|
686
613
|
};
|
|
687
614
|
|
|
688
615
|
TwitterScraper.prototype._get_body_api = function(_arg, cb) {
|
|
689
|
-
var args, body, err, rc, tok, url, ___iced_passed_deferral, __iced_deferrals, __iced_k;
|
|
616
|
+
var args, body, endpoint_name, err, rc, tok, url, ___iced_passed_deferral, __iced_deferrals, __iced_k;
|
|
690
617
|
__iced_k = __iced_k_noop;
|
|
691
618
|
___iced_passed_deferral = iced.findDeferral(arguments);
|
|
692
|
-
url = _arg.url;
|
|
619
|
+
url = _arg.url, endpoint_name = _arg.endpoint_name;
|
|
693
620
|
rc = body = err = null;
|
|
694
621
|
(function(_this) {
|
|
695
622
|
return (function(__iced_k) {
|
|
696
623
|
__iced_deferrals = new iced.Deferrals(__iced_k, {
|
|
697
624
|
parent: ___iced_passed_deferral,
|
|
698
|
-
filename: "/
|
|
625
|
+
filename: "/Users/michal/SourceCode/keybase/go/src/github.com/keybase/server_test_progs/proofs/src/scrapers/twitter.iced",
|
|
699
626
|
funcname: "TwitterScraper._get_body_api"
|
|
700
627
|
});
|
|
701
628
|
_this._get_bearer_token(__iced_deferrals.defer({
|
|
@@ -706,7 +633,7 @@
|
|
|
706
633
|
return tok = arguments[2];
|
|
707
634
|
};
|
|
708
635
|
})(),
|
|
709
|
-
lineno:
|
|
636
|
+
lineno: 358
|
|
710
637
|
}));
|
|
711
638
|
__iced_deferrals._fulfill();
|
|
712
639
|
});
|
|
@@ -721,12 +648,14 @@
|
|
|
721
648
|
Authorization: "Bearer " + tok
|
|
722
649
|
},
|
|
723
650
|
method: "get",
|
|
724
|
-
json: true
|
|
651
|
+
json: true,
|
|
652
|
+
log_ratelimit: endpoint_name != null,
|
|
653
|
+
endpoint_name: endpoint_name
|
|
725
654
|
};
|
|
726
655
|
(function(__iced_k) {
|
|
727
656
|
__iced_deferrals = new iced.Deferrals(__iced_k, {
|
|
728
657
|
parent: ___iced_passed_deferral,
|
|
729
|
-
filename: "/
|
|
658
|
+
filename: "/Users/michal/SourceCode/keybase/go/src/github.com/keybase/server_test_progs/proofs/src/scrapers/twitter.iced",
|
|
730
659
|
funcname: "TwitterScraper._get_body_api"
|
|
731
660
|
});
|
|
732
661
|
_this._get_url_body(args, __iced_deferrals.defer({
|
|
@@ -737,7 +666,7 @@
|
|
|
737
666
|
return body = arguments[2];
|
|
738
667
|
};
|
|
739
668
|
})(),
|
|
740
|
-
lineno:
|
|
669
|
+
lineno: 369
|
|
741
670
|
}));
|
|
742
671
|
__iced_deferrals._fulfill();
|
|
743
672
|
})(__iced_k);
|
package/package.json
CHANGED
package/src/constants.iced
CHANGED
package/src/scrapers/base.iced
CHANGED
|
@@ -79,6 +79,14 @@ class BaseScraper
|
|
|
79
79
|
|
|
80
80
|
#-------------------------------------------------------------
|
|
81
81
|
|
|
82
|
+
_get_rate_limit_header : (headers, name) ->
|
|
83
|
+
# Twitter and Github can't agree on rate limit header names.
|
|
84
|
+
if ((v = parse_int_or_undefined headers.get("X-RateLimit-#{name}")) or
|
|
85
|
+
(v = parse_int_or_undefined headers.get("X-Rate-Limit-#{name}")))
|
|
86
|
+
return v
|
|
87
|
+
else
|
|
88
|
+
return undefined
|
|
89
|
+
|
|
82
90
|
_get_url_body: (opts, cb) ->
|
|
83
91
|
###
|
|
84
92
|
cb(err, status, body) only replies with body if status is 200
|
|
@@ -88,13 +96,17 @@ class BaseScraper
|
|
|
88
96
|
opts.headers["User-Agent"] ?= (opts.user_agent or user_agent)
|
|
89
97
|
await @libs.fetch opts.url, opts, defer(err, response)
|
|
90
98
|
if opts.log_ratelimit and response?
|
|
91
|
-
rl_limit =
|
|
92
|
-
rl_remaining =
|
|
93
|
-
rl_reset =
|
|
99
|
+
rl_limit = @_get_rate_limit_header response.headers, 'Limit' # 5000 for github # https://developer.github.com/v3/#rate-limiting
|
|
100
|
+
rl_remaining = @_get_rate_limit_header response.headers, 'Remaining'
|
|
101
|
+
rl_reset = @_get_rate_limit_header response.headers, 'Reset' # utc timestamp in seconds when limit will replenish
|
|
94
102
|
if rl_limit?
|
|
95
103
|
@log "| ratelimit info limit=#{rl_limit} remaining=#{rl_remaining} reset=#{rl_reset}"
|
|
96
|
-
@libs.ratelimit_inform? {
|
|
97
|
-
|
|
104
|
+
@libs.ratelimit_inform? {
|
|
105
|
+
limit: rl_limit
|
|
106
|
+
remaining: rl_remaining
|
|
107
|
+
reset: rl_reset
|
|
108
|
+
endpoint_name : opts.endpoint_name
|
|
109
|
+
}
|
|
98
110
|
rc = if err?
|
|
99
111
|
if err.message.includes('network timeout') then v_codes.TIMEOUT
|
|
100
112
|
else v_codes.HOST_UNREACHABLE
|
package/src/scrapers/dns.iced
CHANGED
|
@@ -97,13 +97,23 @@ exports.DnsScraper = class DnsScraper extends BaseScraper
|
|
|
97
97
|
|
|
98
98
|
# ---------------------------------------------------------------------------
|
|
99
99
|
|
|
100
|
+
_resolve_txt : (domain, cb) ->
|
|
101
|
+
# We can use a DNS library passed in (in the case of native-dns running on
|
|
102
|
+
# the server)
|
|
103
|
+
dnslib = @libs.dns or dns
|
|
104
|
+
try
|
|
105
|
+
dnslib.resolveTxt domain, (err, records) ->
|
|
106
|
+
cb err, records
|
|
107
|
+
catch err
|
|
108
|
+
cb err
|
|
109
|
+
|
|
110
|
+
# ---------------------------------------------------------------------------
|
|
111
|
+
|
|
100
112
|
# calls back with a v_code or null if it was ok
|
|
101
113
|
_check_status: ({domain, proof_text_check}, cb) ->
|
|
102
114
|
@log "+ DNS check for #{domain}"
|
|
103
115
|
|
|
104
|
-
|
|
105
|
-
dnslib = @libs.dns or dns
|
|
106
|
-
await dnslib.resolveTxt domain, defer err, records
|
|
116
|
+
await @_resolve_txt domain, defer err, records
|
|
107
117
|
rc = if err?
|
|
108
118
|
@log "| DNS error: #{err}"
|
|
109
119
|
v_codes.DNS_ERROR
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
{sncmp,BaseScraper} = require './base'
|
|
1
|
+
{sncmp,BaseScraper,BaseBearerToken} = require './base'
|
|
2
2
|
{make_ids} = require '../base'
|
|
3
3
|
{constants} = require '../constants'
|
|
4
|
-
{Lock} = require '../util'
|
|
5
4
|
{v_codes} = constants
|
|
6
5
|
{decode_sig} = require('kbpgp').ukm
|
|
7
6
|
urlmod = require 'url'
|
|
@@ -17,78 +16,27 @@ ws_normalize = (x) ->
|
|
|
17
16
|
|
|
18
17
|
#================================================================================
|
|
19
18
|
|
|
20
|
-
class
|
|
21
|
-
|
|
22
|
-
#----------------
|
|
23
|
-
|
|
19
|
+
class TwitterBearerToken extends BaseBearerToken
|
|
24
20
|
constructor : ({@base}) ->
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
get : (cb) ->
|
|
33
|
-
await @_lock.acquire defer()
|
|
34
|
-
err = null
|
|
35
|
-
now = Math.floor(Date.now() / 1000)
|
|
36
|
-
|
|
37
|
-
if not (res = @_tok)? or (now - @_created > @auth.lifespan)
|
|
38
|
-
|
|
39
|
-
@base.log "+ Request for bearer token"
|
|
40
|
-
|
|
41
|
-
# Very crypto! Not sure why this is done, but it's done
|
|
42
|
-
cred = (Buffer.from [ @auth.key, @auth.secret].join(":")).toString('base64')
|
|
43
|
-
|
|
44
|
-
req = 'grant_type=client_credentials'
|
|
45
|
-
opts =
|
|
46
|
-
url : "https://api.twitter.com/oauth2/token"
|
|
47
|
-
headers :
|
|
48
|
-
Authorization : "Basic #{cred}"
|
|
49
|
-
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'
|
|
50
|
-
'Content-Length': req.length
|
|
51
|
-
method : "post"
|
|
52
|
-
body : req
|
|
53
|
-
await @base._get_url_body opts, defer err, rc, body
|
|
54
|
-
|
|
55
|
-
if err?
|
|
56
|
-
@base.logl 'error', "In getting bearer_token: #{err.message}"
|
|
57
|
-
else if (rc isnt v_codes.OK)
|
|
58
|
-
@base.logl 'error', "HTTP error in getting bearer token: #{rc}"
|
|
59
|
-
err = new Error "HTTP error: #{rc}"
|
|
60
|
-
else
|
|
61
|
-
try
|
|
62
|
-
body = JSON.parse body
|
|
63
|
-
catch e
|
|
64
|
-
@base.logl 'warn', "Could not parse JSON reply: #{e}"
|
|
65
|
-
err = e
|
|
66
|
-
|
|
67
|
-
if err? then # noop
|
|
68
|
-
else if not (tok = body.access_token)?
|
|
69
|
-
@base.logl 'warn', "No access token found in reply"
|
|
70
|
-
err = new Error "Twitter error: no access token"
|
|
71
|
-
else
|
|
72
|
-
@_tok = tok
|
|
73
|
-
@_created = Math.floor(Date.now() / 1000)
|
|
74
|
-
res = @_tok
|
|
75
|
-
|
|
76
|
-
@base.log "- Request for bearer token -> #{err}"
|
|
77
|
-
|
|
78
|
-
@_lock.release()
|
|
79
|
-
cb err, res
|
|
21
|
+
super {
|
|
22
|
+
name: "Twitter"
|
|
23
|
+
@base
|
|
24
|
+
access_token_url : "https://api.twitter.com/oauth2/token"
|
|
25
|
+
scope : [ 'history', 'read' ]
|
|
26
|
+
}
|
|
80
27
|
|
|
81
28
|
#================================================================================
|
|
82
29
|
|
|
83
30
|
_bearer_token = null
|
|
84
31
|
bearer_token = ({base}) ->
|
|
85
32
|
unless _bearer_token
|
|
86
|
-
_bearer_token = new
|
|
33
|
+
_bearer_token = new TwitterBearerToken { base }
|
|
87
34
|
return _bearer_token
|
|
88
35
|
|
|
89
36
|
#================================================================================
|
|
90
37
|
|
|
91
38
|
exports.TwitterScraper = class TwitterScraper extends BaseScraper
|
|
39
|
+
username_regexp = /^[a-z0-9_-]{2,15}$/
|
|
92
40
|
|
|
93
41
|
constructor: (opts) ->
|
|
94
42
|
@auth = opts.auth
|
|
@@ -101,6 +49,8 @@ exports.TwitterScraper = class TwitterScraper extends BaseScraper
|
|
|
101
49
|
new Error "Bad args to Twitter proof: no username given"
|
|
102
50
|
else if not (args.name?) or (args.name isnt 'twitter')
|
|
103
51
|
new Error "Bad args to Twitter proof: type is #{args.name}"
|
|
52
|
+
else if not args.username.match(username_regexp)
|
|
53
|
+
new Error "Invalid username passed to Twitter proof"
|
|
104
54
|
else
|
|
105
55
|
null
|
|
106
56
|
|
|
@@ -113,25 +63,32 @@ exports.TwitterScraper = class TwitterScraper extends BaseScraper
|
|
|
113
63
|
|
|
114
64
|
return cb(err,out) if (err = @_check_args { username, name })?
|
|
115
65
|
|
|
66
|
+
endpoint_name = "/2/tweets/search/recent"
|
|
116
67
|
u = urlmod.format {
|
|
117
68
|
host : "api.twitter.com"
|
|
118
69
|
protocol : "https:"
|
|
119
|
-
pathname :
|
|
70
|
+
pathname : endpoint_name
|
|
120
71
|
query :
|
|
121
|
-
|
|
122
|
-
screen_name : username
|
|
72
|
+
query : "\"Verifying myself\" \"Keybase.io\" from:#{username}"
|
|
123
73
|
}
|
|
124
|
-
|
|
125
|
-
await @_get_body_api { url : u }, defer err, rc, json
|
|
74
|
+
await @_get_body_api { url : u, endpoint_name }, defer err, rc, json
|
|
126
75
|
@log "| search index #{u} -> #{rc}"
|
|
127
76
|
if rc isnt v_codes.OK then #noop
|
|
128
77
|
else if not json? or (json.length is 0) then rc = v_codes.EMPTY_JSON
|
|
78
|
+
else if not json.data?
|
|
79
|
+
if json.meta?.result_count is 0
|
|
80
|
+
# No results.
|
|
81
|
+
rc = v_codes.NOT_FOUND
|
|
82
|
+
else
|
|
83
|
+
# Unknown JSON structure.
|
|
84
|
+
rc = v_codes.INVALID_JSON
|
|
129
85
|
else
|
|
130
|
-
|
|
86
|
+
rc = v_codes.NOT_FOUND
|
|
87
|
+
for {text, id},i in json.data
|
|
131
88
|
if (@find_sig_in_tweet { inside : text, proof_text_check }) is v_codes.OK
|
|
132
89
|
@log "| found valid tweet in stream @ #{i}"
|
|
133
90
|
rc = v_codes.OK
|
|
134
|
-
remote_id =
|
|
91
|
+
remote_id = id
|
|
135
92
|
api_url = human_url = @_id_to_url username, remote_id
|
|
136
93
|
out = { remote_id, api_url, human_url }
|
|
137
94
|
break
|
|
@@ -397,7 +354,7 @@ exports.TwitterScraper = class TwitterScraper extends BaseScraper
|
|
|
397
354
|
# ---------------------------------------------------------------------------
|
|
398
355
|
|
|
399
356
|
# Only the hunter needs this
|
|
400
|
-
_get_body_api : ({url}, cb) ->
|
|
357
|
+
_get_body_api : ({url, endpoint_name}, cb) ->
|
|
401
358
|
rc = body = err = null
|
|
402
359
|
await @_get_bearer_token defer err, rc, tok
|
|
403
360
|
unless err?
|
|
@@ -408,6 +365,8 @@ exports.TwitterScraper = class TwitterScraper extends BaseScraper
|
|
|
408
365
|
Authorization : "Bearer #{tok}"
|
|
409
366
|
method : "get"
|
|
410
367
|
json : true
|
|
368
|
+
log_ratelimit : endpoint_name?
|
|
369
|
+
endpoint_name : endpoint_name
|
|
411
370
|
await @_get_url_body args, defer err, rc, body
|
|
412
371
|
cb err, rc, body
|
|
413
372
|
|
package/SIGNED.md
DELETED
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
##### Signed by https://keybase.io/max
|
|
2
|
-
```
|
|
3
|
-
-----BEGIN PGP SIGNATURE-----
|
|
4
|
-
Comment: GPGTools - https://gpgtools.org
|
|
5
|
-
|
|
6
|
-
iQEcBAABCgAGBQJWBZ3PAAoJEJgKPw0B/gTfPrkIALMDLUb+CS2oPrFZlILoC31o
|
|
7
|
-
FUKtCiN+hzC9+FgMYp18kWsWDh3DxzqPIRs28mwt9QMQTHdywv6K+nfQw2dE4wns
|
|
8
|
-
1Wi7ZVPbvR5P0/ANIQ0QwetYxbkNow20dU67CRj0aEvvbopQDBgBgyH9b6LjSb+n
|
|
9
|
-
8OTUFLhtiXN0PeZJ5/OyMtq8jyrjT7MEpxAb+8uFt95fPax17TNjCBEF4mlNqvtl
|
|
10
|
-
YIOd/1v6YTlaqbYSzEZoMZsSI12UGK/tLaPG6qYf+5gGi96YjEMuQyDsL7ANQpkG
|
|
11
|
-
jplkuKpykiY1Ndc1B3TOnTK8n+lrRaWesLmHnhldhR047ZNYgETunz+NYks7MHI=
|
|
12
|
-
=96ur
|
|
13
|
-
-----END PGP SIGNATURE-----
|
|
14
|
-
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
<!-- END SIGNATURES -->
|
|
18
|
-
|
|
19
|
-
### Begin signed statement
|
|
20
|
-
|
|
21
|
-
#### Expect
|
|
22
|
-
|
|
23
|
-
```
|
|
24
|
-
size exec file contents
|
|
25
|
-
./
|
|
26
|
-
109 .gitignore ec278daeb8f83cac2579d262b92ee6d7d872c4d1544e881ba515d8bcc05361ab
|
|
27
|
-
10709 CHANGELOG.md 8ce81ae853a72be10648f712497199b316dfe57c8519853687cee1b508965af1
|
|
28
|
-
66 CONTIBUTORS.md e5a536ada9dc7f25b352f28cc8936db4ded1a0860f6f23ef61d0b14aeae351da
|
|
29
|
-
1483 LICENSE 333be7050513d91d9e77ca9acb4a91261721f0050209636076ed58676bfc643d
|
|
30
|
-
1383 Makefile b90c2b9165497660a610d5ec6177b854aafaa318aa1252af23484c755f1d959a
|
|
31
|
-
43 README.md b2db580fc880756ae739bb148570f6afb1c250e5c0d2c5fa56ce41491753ca6c
|
|
32
|
-
lib/
|
|
33
|
-
2498 alloc.js af1347e6f17197fee04fba783839279b07b07f79bf407ddf44e09d360289aa48
|
|
34
|
-
1189 announcement.js ff01f39dca21c1387faa8b79633dec40414f5645886015a46bd795772987c79e
|
|
35
|
-
1383 auth.js 86403419686d1cac766c8d3d6c8f6e10176694e33de84faafca652fd01e54e0e
|
|
36
|
-
766 b64extract.js 1466f81bb930ddc439f877ef0cba4d20048f5477aafda294290f0fd0da527073
|
|
37
|
-
33694 base.js b57791baad7fd3b648749320875ada1adc6e8d0dc3265c6f2fe4faeb960c05bb
|
|
38
|
-
2043 constants.js e88df2ce555fe3fa8f70bbac3ebdca7c169571cbd5055948ecd8215e231d75fb
|
|
39
|
-
1382 cryptocurrency.js 40536713081183e8b698a345df9a288a0967e1c95bd0699fe8ea18b618a6de6a
|
|
40
|
-
1087 device.js f77d694ccf19c81b8c1977bb5c0280979a8b15983ced95675d6f5d44cedf67a7
|
|
41
|
-
1294 eldest.js 878cc36219a2d25c1e1897a672f03b5d97ece05581b6ece7707e78cbb0a8e02e
|
|
42
|
-
909 main.js 1cc4c7fd9cfee3ce317d8993507a953c8a22803eaea69eb16d4c7be9c0d7731b
|
|
43
|
-
1549 pgp_update.js c084bee65b6e7cee2d9fd7ddeea107751a319c03831205005ed997fa4840f939
|
|
44
|
-
2578 revoke.js 57106f23d108ce01a6d781a795417c86a09633af73ff1c9630d3893a8bc47e5f
|
|
45
|
-
scrapers/
|
|
46
|
-
6392 base.js db98e2349217287c98feba718b0bdd9570c5e1108370942af9ca2a2b59be5ed9
|
|
47
|
-
15450 bitbucket.js 7530f245a6836d29177cae7e2a1e0efa9860e1adc9965731cf1e79c5f82f3f4c
|
|
48
|
-
4137 coinbase.js 5d28f2c525f69e64881d0ae5dd38c535a324f894d98b67d1a5b8217a4c564ce3
|
|
49
|
-
8239 dns.js 74ced258122595b80997594c4f8fb82c210b5f316848b035b2b66582bb6052e8
|
|
50
|
-
9369 generic_web_site.js aa3fff8c4d36f86182666642117ec71c4c1574d44eeeba675f698d08fb9a1edd
|
|
51
|
-
9901 github.js 221586b7fd13ec28a51479319902fdb143a1b37d25dcdb7926826b100917ffbd
|
|
52
|
-
5995 hackernews.js 0e73885c9dba4dbba56fc042afe6002aeae1699094f77555c831d2a15348033c
|
|
53
|
-
8535 reddit.js 508d1b349ce6a992afe5c882d7c541c1ff85990645343dbfd748c09888d8ce3f
|
|
54
|
-
27418 twitter.js fda7930b6de79013601c22d0585833e6c2bf09594ec7890a4852ef3e21d24df5
|
|
55
|
-
1774 sibkey.js b434bb5e226214d5113eae44201ead14e7430bc92e56e2446e80d2cf9076ab1d
|
|
56
|
-
10983 subkey.js 76aca817ffb548ffe3dd668d9c2b189c3c3040300f748c6acf105c5f5a5dae82
|
|
57
|
-
1669 track.js b85423eb1309ac58f5cb2b68697f612c091ef2d44fa8cc9e4b85ab6039ae8b9a
|
|
58
|
-
1506 update_passphrase_hash.js f2cfce382fd677e31a88f3646eb2d90258583a1ef68fe74dcd178a2e178229f6
|
|
59
|
-
1544 util.js 1760f3955e71bed8a332c02a1c9a96733f9af0e0f297c89ec354f83ed5bf3908
|
|
60
|
-
19530 web_service.js 769a2c81aeb9b76ec627126776c346c20209ed588536dca528a617b5fbcdc553
|
|
61
|
-
744 package.json b670f8f7efdd7d69fa92f089729bdfe4486ded548e03b677bab888e3e21f2ab0
|
|
62
|
-
src/
|
|
63
|
-
2376 alloc.iced bce30dc075d16e0551aeb8ce89f2a0515e8b061f7cbd1c9842a93756c028254b
|
|
64
|
-
537 announcement.iced 98ddc17f5c6b66874ed2a273032d5c5e118d1ef3a7f5a08f4c7fb9cf06e811cf
|
|
65
|
-
671 auth.iced 3f0f211734a2f8408a5f5e1f5c353cad3373f952b01209f0f2d644b681612b0e
|
|
66
|
-
704 b64extract.iced 47b06460fd61d8eb788878566c62086b1fd1f792a1712b3e8736766401bc8fee
|
|
67
|
-
15746 base.iced cbd3229cab90232ce33ca7ced8c2d492c2eaa5091a48019486f401f3df689f4a
|
|
68
|
-
2264 constants.iced ed833b20ade7e8e95d1e4c65577cfb8e7de20b554afaf7aaa7963e86d5f2b370
|
|
69
|
-
609 cryptocurrency.iced 9c839bdd1c12591ca73c6fbc86d44c51f1803718d37286e9eade945bee0761d1
|
|
70
|
-
489 device.iced b0c028eb2598c48d9d24be615e066e0a03e8b7b1930a4ca58f29d23517daf0bc
|
|
71
|
-
566 eldest.iced 8dd63bec35fca4ab933de049888777e957827a862ecf2dec7e91e91e4265917c
|
|
72
|
-
741 main.iced 0c4af12c6c069e3ece0f446c922ba8f306df4f386e3bee3c4ba852bc92a4df0b
|
|
73
|
-
589 pgp_update.iced cdc5fed1d47c0bfe144062cf7985d466ced99fb8ec7bd17901d504127359fc64
|
|
74
|
-
788 revoke.iced 2b94671a923dcdd274d0f769f186f0757a27db64828eaad5fa5eb1a24f9e479f
|
|
75
|
-
scrapers/
|
|
76
|
-
4029 base.iced e110786284dda6cd78bc0be507ff9ac0add3a128c959c073562416b513d8b2d8
|
|
77
|
-
3967 bitbucket.iced f22e9c29d781afbecccc0c720513fa63710e3c199cc9780ef34b87a4db0e1fd9
|
|
78
|
-
2370 coinbase.iced 5b1132561f0c33d4c35ba2d7d9c32200e77d83c68a3bce3d770b27085d649bcd
|
|
79
|
-
4081 dns.iced 773ea8e65f46b2db994e41ed4849c4637200ee2e978f280524d63b06a42ff454
|
|
80
|
-
3249 generic_web_site.iced 7a70be6c922e5adb73459973b81143ec9020b109cdbcc5acf349e47c5ca1f68d
|
|
81
|
-
3305 github.iced f10410ccca3bb3fc5045024dada97a4974984ee433476bea30c1ab47f870da90
|
|
82
|
-
2909 hackernews.iced cb14793b3ea889bcbc2121430bc3728655e125806001211864d3c90c1104505a
|
|
83
|
-
4082 reddit.iced 8a4f6902eee7e1609df18bf9a00b5934d2e9a16eaf20bd6231b3d11b2554effe
|
|
84
|
-
11418 twitter.iced 9bbb6cfdc464a5ed3261cc8f1a14a12e18325d6b0edc753c7a9e133b58d9328e
|
|
85
|
-
761 sibkey.iced 308c4cfef33dbc79809600a46c4f1704d4240be18478d2e5e8f71e523fd6962d
|
|
86
|
-
3503 subkey.iced 6f41a5aa38813486cbcb5a3c918c2e7aa464665b9dac852f92bb62ffa1e0a3b1
|
|
87
|
-
838 track.iced d72d0eb5cda7f0f9800f17225fedf552f45111b802f66c463c4408794bd11aca
|
|
88
|
-
658 update_passphrase_hash.iced ea87dd15d3a36ee581e48a5436f4c64f38a102906efcdc20bc925b821210bfd9
|
|
89
|
-
1052 util.iced 88092afaf23bf8dfe42a72252ac156be45e94588911584ecf535d228b108f2b9
|
|
90
|
-
10177 web_service.iced bb436e165233be85342d0abe01237fcfb5773b0cc050abef49f1f19094abd8f0
|
|
91
|
-
1673 test_scraper.iced 099823ea87768b45dd205bd6dc36773999730dadb26fe3844e0a05f8668bb9d1
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
#### Ignore
|
|
95
|
-
|
|
96
|
-
```
|
|
97
|
-
/SIGNED.md
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
#### Presets
|
|
101
|
-
|
|
102
|
-
```
|
|
103
|
-
git # ignore .git and anything as described by .gitignore files
|
|
104
|
-
dropbox # ignore .dropbox-cache and other Dropbox-related files
|
|
105
|
-
kb # ignore anything as described by .kbignore files
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
<!-- summarize version = 0.0.9 -->
|
|
109
|
-
|
|
110
|
-
### End signed statement
|
|
111
|
-
|
|
112
|
-
<hr>
|
|
113
|
-
|
|
114
|
-
#### Notes
|
|
115
|
-
|
|
116
|
-
With keybase you can sign any directory's contents, whether it's a git repo,
|
|
117
|
-
source code distribution, or a personal documents folder. It aims to replace the drudgery of:
|
|
118
|
-
|
|
119
|
-
1. comparing a zipped file to a detached statement
|
|
120
|
-
2. downloading a public key
|
|
121
|
-
3. confirming it is in fact the author's by reviewing public statements they've made, using it
|
|
122
|
-
|
|
123
|
-
All in one simple command:
|
|
124
|
-
|
|
125
|
-
```bash
|
|
126
|
-
keybase dir verify
|
|
127
|
-
```
|
|
128
|
-
|
|
129
|
-
There are lots of options, including assertions for automating your checks.
|
|
130
|
-
|
|
131
|
-
For more info, check out https://keybase.io/docs/command_line/code_signing
|