Skip to content

Commit e2f61e3

Browse files
committed
include binaries for the release
1 parent 512e039 commit e2f61e3

File tree

192 files changed

+24323
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

192 files changed

+24323
-0
lines changed
+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
2+
// this text contains an JSON array of JWKS files
3+
const CLIENT_JWKS = {
4+
'jba' : ${jba_jwks_key}
5+
,
6+
'jbt' : ${jbt_jwks_key}
7+
}
8+
9+
exports.CLIENT_SECRET = CLIENT_JWKS;

lambda-release/lambda.js

+122
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
const jwt = require('jsonwebtoken');
2+
const jwkToPem = require('jwk-to-pem');
3+
4+
// if the file is missing, make sure build-lambda.js was executed
5+
const {CLIENT_SECRET: {jba: jba_keys_data = {}, jbt: jbt_keys_data = {}}} = require('./jwks-generated.js');
6+
7+
function prepareKey(modeName, json, handler) {
8+
console.log("The JWKS for " + modeName + " :")
9+
console.log(JSON.stringify(json, null, ' '))
10+
11+
const keys = json.keys || [];
12+
const selectedKeys = [];
13+
for (const key of keys) {
14+
const ourAlg = key.alg;
15+
if (!ourAlg) throw new Error("Unexpected different key alg: " + ourAlg)
16+
const ourKid = key.kid || null;
17+
const keyPem = jwkToPem(key);
18+
selectedKeys.push({
19+
modeName: modeName,
20+
algorithms: [ourAlg],
21+
jwksGetKey: function (header, callback) {
22+
let theirKid = header.kid || null;
23+
let theirAlg = header.alg;
24+
25+
if (ourAlg !== theirAlg) {
26+
callback(new Error("Unknown alg"), null);
27+
return;
28+
}
29+
30+
if (ourKid !== theirKid) {
31+
callback(new Error("Unknown kid"), null);
32+
return;
33+
}
34+
35+
callback(null, keyPem);
36+
},
37+
38+
verifyCallback: payload => handler(payload)
39+
}
40+
);
41+
}
42+
43+
return selectedKeys;
44+
}
45+
46+
const jbaJwtKeys = prepareKey('JBA', jba_keys_data, ({email = '', sub = ''}) => sub.toString().toLowerCase().endsWith("@jetbrains.com") || email.toString().toLowerCase().endsWith("@jetbrains.com"));
47+
const jbtJwtKeys = prepareKey('JBT', jbt_keys_data, ({orgDomain = ''}) => orgDomain.toString().toLowerCase() === 'jetbrains');
48+
const allJwtKeys = [...jbtJwtKeys, ...jbaJwtKeys];
49+
50+
function parseToken(headers) {
51+
//see https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-examples.html
52+
const {authorization = []} = headers;
53+
if (authorization.length > 0) {
54+
for (let i = 0; i < authorization.length; i++) {
55+
const token = authorization[i].value || ''
56+
const prefix = 'bearer ';
57+
if (token.toLowerCase().startsWith(prefix)) {
58+
return token.substring(prefix.length)
59+
}
60+
}
61+
}
62+
63+
return null;
64+
}
65+
66+
function notAuthorized() {
67+
return {
68+
status: '403',
69+
statusDescription: 'Not Authorized by JetBrains',
70+
body: '403. Not Authorized by JetBrains',
71+
headers: {
72+
'cache-control': [{
73+
key: 'Cache-Control',
74+
value: 'no-cache, max-age=0'
75+
}],
76+
'content-type': [{
77+
key: 'Content-Type',
78+
value: 'text/plain; charset=UTF-8'
79+
}],
80+
'x-content-type-options': [{
81+
key: 'X-Content-Type-Options',
82+
value: 'nosniff'
83+
}]
84+
},
85+
};
86+
}
87+
88+
async function handler(request) {
89+
const token = parseToken(request.headers)
90+
if (!token) {
91+
return notAuthorized()
92+
}
93+
94+
for (const jwtKey of allJwtKeys) {
95+
let result = await new Promise((resolve) => {
96+
jwt.verify(token, jwtKey.jwksGetKey, {algorithms: jwtKey.algorithms}, (err, payload) => {
97+
if (err != null || payload === undefined || payload === null) {
98+
console.log(jwtKey.modeName + ': Failed to verify token.', (err.message || err));
99+
resolve(false);
100+
return;
101+
}
102+
console.log(jwtKey.modeName + ": payload " + JSON.stringify(payload, null, ' '));
103+
resolve(jwtKey.verifyCallback(payload));
104+
});
105+
});
106+
107+
if (result === true) return request;
108+
}
109+
110+
return notAuthorized()
111+
}
112+
113+
exports.handler = async (event, context) => {
114+
try {
115+
const request = event.Records[0].cf.request;
116+
return await handler(request)
117+
} catch (err) {
118+
// token exists but it-is invalid
119+
console.log('Crashed to verify a token', err);
120+
return notAuthorized();
121+
}
122+
};

lambda-release/node_modules/.bin/semver

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lambda-release/node_modules/asn1.js/.eslintrc.js

+27
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lambda-release/node_modules/asn1.js/LICENSE

+21
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lambda-release/node_modules/asn1.js/README.md

+100
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lambda-release/node_modules/asn1.js/lib/asn1.js

+11
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lambda-release/node_modules/asn1.js/lib/asn1/api.js

+57
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)