keybase-proofs 2.3.26 → 2.3.28
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 +8 -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 +59 -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 +23 -70
- package/SIGNED.md +0 -131
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
## 2.3.28 (2024-07-19)
|
|
2
|
+
|
|
3
|
+
- Use version 2 API for X (formerly known as Twitter) hunting.
|
|
4
|
+
|
|
5
|
+
## 2.3.27 (2024-07-18)
|
|
6
|
+
|
|
7
|
+
- Fix error handling when an invalid unicode domain is passed to DnsScraper.
|
|
8
|
+
|
|
1
9
|
## 2.3.26 (2024-06-17)
|
|
2
10
|
|
|
3
11
|
- 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,32 @@
|
|
|
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;
|
|
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
|
+
rc = v_codes.INVALID_JSON;
|
|
223
144
|
} else {
|
|
224
|
-
|
|
225
|
-
|
|
145
|
+
rc = v_codes.NOT_FOUND;
|
|
146
|
+
_ref1 = json.data;
|
|
147
|
+
for (i = _i = 0, _len = _ref1.length; _i < _len; i = ++_i) {
|
|
148
|
+
_ref2 = _ref1[i], text = _ref2.text, id = _ref2.id;
|
|
226
149
|
if ((_this.find_sig_in_tweet({
|
|
227
150
|
inside: text,
|
|
228
151
|
proof_text_check: proof_text_check
|
|
229
152
|
})) === v_codes.OK) {
|
|
230
153
|
_this.log("| found valid tweet in stream @ " + i);
|
|
231
154
|
rc = v_codes.OK;
|
|
232
|
-
remote_id =
|
|
155
|
+
remote_id = id;
|
|
233
156
|
api_url = human_url = _this._id_to_url(username, remote_id);
|
|
234
157
|
out = {
|
|
235
158
|
remote_id: remote_id,
|
|
@@ -295,7 +218,7 @@
|
|
|
295
218
|
(function(__iced_k) {
|
|
296
219
|
__iced_deferrals = new iced.Deferrals(__iced_k, {
|
|
297
220
|
parent: ___iced_passed_deferral,
|
|
298
|
-
filename: "/
|
|
221
|
+
filename: "/Users/michal/SourceCode/keybase/go/src/github.com/keybase/server_test_progs/proofs/src/scrapers/twitter.iced",
|
|
299
222
|
funcname: "TwitterScraper.users_lookup"
|
|
300
223
|
});
|
|
301
224
|
_this._get_body_api({
|
|
@@ -308,7 +231,7 @@
|
|
|
308
231
|
return json = arguments[2];
|
|
309
232
|
};
|
|
310
233
|
})(),
|
|
311
|
-
lineno:
|
|
234
|
+
lineno: 123
|
|
312
235
|
}));
|
|
313
236
|
__iced_deferrals._fulfill();
|
|
314
237
|
})(function() {
|
|
@@ -338,11 +261,11 @@
|
|
|
338
261
|
(function(__iced_k) {
|
|
339
262
|
__iced_deferrals = new iced.Deferrals(__iced_k, {
|
|
340
263
|
parent: ___iced_passed_deferral,
|
|
341
|
-
filename: "/
|
|
264
|
+
filename: "/Users/michal/SourceCode/keybase/go/src/github.com/keybase/server_test_progs/proofs/src/scrapers/twitter.iced",
|
|
342
265
|
funcname: "TwitterScraper.users_lookup"
|
|
343
266
|
});
|
|
344
267
|
setTimeout(__iced_deferrals.defer({
|
|
345
|
-
lineno:
|
|
268
|
+
lineno: 137
|
|
346
269
|
}), cursor_wait);
|
|
347
270
|
__iced_deferrals._fulfill();
|
|
348
271
|
})(__iced_k);
|
|
@@ -424,7 +347,7 @@
|
|
|
424
347
|
(function(__iced_k) {
|
|
425
348
|
__iced_deferrals = new iced.Deferrals(__iced_k, {
|
|
426
349
|
parent: ___iced_passed_deferral,
|
|
427
|
-
filename: "/
|
|
350
|
+
filename: "/Users/michal/SourceCode/keybase/go/src/github.com/keybase/server_test_progs/proofs/src/scrapers/twitter.iced",
|
|
428
351
|
funcname: "TwitterScraper.get_follower_ids"
|
|
429
352
|
});
|
|
430
353
|
_this._get_body_api({
|
|
@@ -437,7 +360,7 @@
|
|
|
437
360
|
return json = arguments[2];
|
|
438
361
|
};
|
|
439
362
|
})(),
|
|
440
|
-
lineno:
|
|
363
|
+
lineno: 175
|
|
441
364
|
}));
|
|
442
365
|
__iced_deferrals._fulfill();
|
|
443
366
|
})(function() {
|
|
@@ -470,11 +393,11 @@
|
|
|
470
393
|
(function(__iced_k) {
|
|
471
394
|
__iced_deferrals = new iced.Deferrals(__iced_k, {
|
|
472
395
|
parent: ___iced_passed_deferral,
|
|
473
|
-
filename: "/
|
|
396
|
+
filename: "/Users/michal/SourceCode/keybase/go/src/github.com/keybase/server_test_progs/proofs/src/scrapers/twitter.iced",
|
|
474
397
|
funcname: "TwitterScraper.get_follower_ids"
|
|
475
398
|
});
|
|
476
399
|
setTimeout(__iced_deferrals.defer({
|
|
477
|
-
lineno:
|
|
400
|
+
lineno: 191
|
|
478
401
|
}), cursor_wait);
|
|
479
402
|
__iced_deferrals._fulfill();
|
|
480
403
|
})(__iced_k);
|
|
@@ -576,7 +499,7 @@
|
|
|
576
499
|
return (function(__iced_k) {
|
|
577
500
|
__iced_deferrals = new iced.Deferrals(__iced_k, {
|
|
578
501
|
parent: ___iced_passed_deferral,
|
|
579
|
-
filename: "/
|
|
502
|
+
filename: "/Users/michal/SourceCode/keybase/go/src/github.com/keybase/server_test_progs/proofs/src/scrapers/twitter.iced",
|
|
580
503
|
funcname: "TwitterScraper.check_status"
|
|
581
504
|
});
|
|
582
505
|
_this._get_url_body({
|
|
@@ -590,7 +513,7 @@
|
|
|
590
513
|
return body_obj = arguments[2];
|
|
591
514
|
};
|
|
592
515
|
})(),
|
|
593
|
-
lineno:
|
|
516
|
+
lineno: 282
|
|
594
517
|
}));
|
|
595
518
|
__iced_deferrals._fulfill();
|
|
596
519
|
});
|
|
@@ -663,7 +586,7 @@
|
|
|
663
586
|
return (function(__iced_k) {
|
|
664
587
|
__iced_deferrals = new iced.Deferrals(__iced_k, {
|
|
665
588
|
parent: ___iced_passed_deferral,
|
|
666
|
-
filename: "/
|
|
589
|
+
filename: "/Users/michal/SourceCode/keybase/go/src/github.com/keybase/server_test_progs/proofs/src/scrapers/twitter.iced",
|
|
667
590
|
funcname: "TwitterScraper._get_bearer_token"
|
|
668
591
|
});
|
|
669
592
|
bt.get(__iced_deferrals.defer({
|
|
@@ -673,7 +596,7 @@
|
|
|
673
596
|
return tok = arguments[1];
|
|
674
597
|
};
|
|
675
598
|
})(),
|
|
676
|
-
lineno:
|
|
599
|
+
lineno: 343
|
|
677
600
|
}));
|
|
678
601
|
__iced_deferrals._fulfill();
|
|
679
602
|
});
|
|
@@ -686,16 +609,16 @@
|
|
|
686
609
|
};
|
|
687
610
|
|
|
688
611
|
TwitterScraper.prototype._get_body_api = function(_arg, cb) {
|
|
689
|
-
var args, body, err, rc, tok, url, ___iced_passed_deferral, __iced_deferrals, __iced_k;
|
|
612
|
+
var args, body, endpoint_name, err, rc, tok, url, ___iced_passed_deferral, __iced_deferrals, __iced_k;
|
|
690
613
|
__iced_k = __iced_k_noop;
|
|
691
614
|
___iced_passed_deferral = iced.findDeferral(arguments);
|
|
692
|
-
url = _arg.url;
|
|
615
|
+
url = _arg.url, endpoint_name = _arg.endpoint_name;
|
|
693
616
|
rc = body = err = null;
|
|
694
617
|
(function(_this) {
|
|
695
618
|
return (function(__iced_k) {
|
|
696
619
|
__iced_deferrals = new iced.Deferrals(__iced_k, {
|
|
697
620
|
parent: ___iced_passed_deferral,
|
|
698
|
-
filename: "/
|
|
621
|
+
filename: "/Users/michal/SourceCode/keybase/go/src/github.com/keybase/server_test_progs/proofs/src/scrapers/twitter.iced",
|
|
699
622
|
funcname: "TwitterScraper._get_body_api"
|
|
700
623
|
});
|
|
701
624
|
_this._get_bearer_token(__iced_deferrals.defer({
|
|
@@ -706,7 +629,7 @@
|
|
|
706
629
|
return tok = arguments[2];
|
|
707
630
|
};
|
|
708
631
|
})(),
|
|
709
|
-
lineno:
|
|
632
|
+
lineno: 352
|
|
710
633
|
}));
|
|
711
634
|
__iced_deferrals._fulfill();
|
|
712
635
|
});
|
|
@@ -721,12 +644,14 @@
|
|
|
721
644
|
Authorization: "Bearer " + tok
|
|
722
645
|
},
|
|
723
646
|
method: "get",
|
|
724
|
-
json: true
|
|
647
|
+
json: true,
|
|
648
|
+
log_ratelimit: endpoint_name != null,
|
|
649
|
+
endpoint_name: endpoint_name
|
|
725
650
|
};
|
|
726
651
|
(function(__iced_k) {
|
|
727
652
|
__iced_deferrals = new iced.Deferrals(__iced_k, {
|
|
728
653
|
parent: ___iced_passed_deferral,
|
|
729
|
-
filename: "/
|
|
654
|
+
filename: "/Users/michal/SourceCode/keybase/go/src/github.com/keybase/server_test_progs/proofs/src/scrapers/twitter.iced",
|
|
730
655
|
funcname: "TwitterScraper._get_body_api"
|
|
731
656
|
});
|
|
732
657
|
_this._get_url_body(args, __iced_deferrals.defer({
|
|
@@ -737,7 +662,7 @@
|
|
|
737
662
|
return body = arguments[2];
|
|
738
663
|
};
|
|
739
664
|
})(),
|
|
740
|
-
lineno:
|
|
665
|
+
lineno: 363
|
|
741
666
|
}));
|
|
742
667
|
__iced_deferrals._fulfill();
|
|
743
668
|
})(__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,26 @@ 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? then rc = v_codes.INVALID_JSON
|
|
129
79
|
else
|
|
130
|
-
|
|
80
|
+
rc = v_codes.NOT_FOUND
|
|
81
|
+
for {text, id},i in json.data
|
|
131
82
|
if (@find_sig_in_tweet { inside : text, proof_text_check }) is v_codes.OK
|
|
132
83
|
@log "| found valid tweet in stream @ #{i}"
|
|
133
84
|
rc = v_codes.OK
|
|
134
|
-
remote_id =
|
|
85
|
+
remote_id = id
|
|
135
86
|
api_url = human_url = @_id_to_url username, remote_id
|
|
136
87
|
out = { remote_id, api_url, human_url }
|
|
137
88
|
break
|
|
@@ -397,7 +348,7 @@ exports.TwitterScraper = class TwitterScraper extends BaseScraper
|
|
|
397
348
|
# ---------------------------------------------------------------------------
|
|
398
349
|
|
|
399
350
|
# Only the hunter needs this
|
|
400
|
-
_get_body_api : ({url}, cb) ->
|
|
351
|
+
_get_body_api : ({url, endpoint_name}, cb) ->
|
|
401
352
|
rc = body = err = null
|
|
402
353
|
await @_get_bearer_token defer err, rc, tok
|
|
403
354
|
unless err?
|
|
@@ -408,6 +359,8 @@ exports.TwitterScraper = class TwitterScraper extends BaseScraper
|
|
|
408
359
|
Authorization : "Bearer #{tok}"
|
|
409
360
|
method : "get"
|
|
410
361
|
json : true
|
|
362
|
+
log_ratelimit : endpoint_name?
|
|
363
|
+
endpoint_name : endpoint_name
|
|
411
364
|
await @_get_url_body args, defer err, rc, body
|
|
412
365
|
cb err, rc, body
|
|
413
366
|
|
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
|