Prettify everything

This commit is contained in:
MICHAEL JACKSON
2018-02-17 18:00:56 -08:00
parent d6f2bc089a
commit 2e1f09e913
58 changed files with 1061 additions and 932 deletions

View File

@ -3,37 +3,38 @@
* permissions. Otherwise rejects the request.
*/
function requireAuth(scope) {
let checkScopes
let checkScopes;
if (scope.includes(".")) {
const parts = scope.split(".")
checkScopes = scopes => parts.reduce((memo, part) => memo && memo[part], scopes) != null
const parts = scope.split(".");
checkScopes = scopes =>
parts.reduce((memo, part) => memo && memo[part], scopes) != null;
} else {
checkScopes = scopes => scopes[scope] != null
checkScopes = scopes => scopes[scope] != null;
}
return function(req, res, next) {
if (req.auth && req.auth.includes(scope)) {
return next() // Already auth'd
return next(); // Already auth'd
}
const user = req.user
const user = req.user;
if (!user) {
return res.status(403).send({ error: "Missing auth token" })
return res.status(403).send({ error: "Missing auth token" });
}
if (!user.scopes || !checkScopes(user.scopes)) {
return res.status(403).send({ error: "Insufficient scopes" })
return res.status(403).send({ error: "Insufficient scopes" });
}
if (req.auth) {
req.auth.push(scope)
req.auth.push(scope);
} else {
req.auth = [scope]
req.auth = [scope];
}
next()
}
next();
};
}
module.exports = requireAuth
module.exports = requireAuth;

View File

@ -1,41 +1,41 @@
const AuthAPI = require("../AuthAPI")
const AuthAPI = require("../AuthAPI");
const ReadMethods = { GET: true, HEAD: true }
const ReadMethods = { GET: true, HEAD: true };
/**
* Sets req.user from the payload in the auth token in the request.
*/
function userToken(req, res, next) {
if (req.user) {
return next()
return next();
}
const token = (ReadMethods[req.method] ? req.query : req.body).token
const token = (ReadMethods[req.method] ? req.query : req.body).token;
if (!token) {
req.user = null
return next()
req.user = null;
return next();
}
AuthAPI.verifyToken(token).then(
payload => {
req.user = payload
next()
req.user = payload;
next();
},
error => {
if (error.name === "JsonWebTokenError") {
res.status(403).send({
error: `Bad auth token: ${error.message}`
})
});
} else {
console.error(error)
console.error(error);
res.status(500).send({
error: "Unable to verify auth"
})
});
}
}
)
);
}
module.exports = userToken
module.exports = userToken;

View File

@ -1,29 +1,29 @@
const db = require("../../RedisClient")
const db = require("../../RedisClient");
function createCache(keyPrefix) {
function createKey(key) {
return keyPrefix + "-" + key
return keyPrefix + "-" + key;
}
function set(key, value, expiry, callback) {
db.setex(createKey(key), expiry, JSON.stringify(value), callback)
db.setex(createKey(key), expiry, JSON.stringify(value), callback);
}
function get(key, callback) {
db.get(createKey(key), function(error, value) {
callback(error, value && JSON.parse(value))
})
callback(error, value && JSON.parse(value));
});
}
function del(key, callback) {
db.del(createKey(key), callback)
db.del(createKey(key), callback);
}
return {
set,
get,
del
}
};
}
module.exports = createCache
module.exports = createCache;

View File

@ -1,24 +1,24 @@
function createMutex(doWork) {
const mutex = {}
const mutex = {};
return function(key, payload, callback) {
if (mutex[key]) {
mutex[key].push(callback)
mutex[key].push(callback);
} else {
mutex[key] = [
function() {
delete mutex[key]
delete mutex[key];
},
callback
]
];
doWork(payload, function(error, value) {
mutex[key].forEach(callback => {
callback(error, value)
})
})
callback(error, value);
});
});
}
}
};
}
module.exports = createMutex
module.exports = createMutex;

View File

@ -1,17 +1,17 @@
function createSearch(query) {
const params = []
const params = [];
Object.keys(query).forEach(param => {
if (query[param] === "") {
params.push(param) // Omit the trailing "=" from param=
params.push(param); // Omit the trailing "=" from param=
} else {
params.push(`${param}=${encodeURIComponent(query[param])}`)
params.push(`${param}=${encodeURIComponent(query[param])}`);
}
})
});
const search = params.join("&")
const search = params.join("&");
return search ? `?${search}` : ""
return search ? `?${search}` : "";
}
module.exports = createSearch
module.exports = createSearch;

View File

@ -1,15 +1,15 @@
require("isomorphic-fetch")
const fs = require("fs")
const path = require("path")
const tmpdir = require("os-tmpdir")
const gunzip = require("gunzip-maybe")
const mkdirp = require("mkdirp")
const tar = require("tar-fs")
const createMutex = require("./createMutex")
require("isomorphic-fetch");
const fs = require("fs");
const path = require("path");
const tmpdir = require("os-tmpdir");
const gunzip = require("gunzip-maybe");
const mkdirp = require("mkdirp");
const tar = require("tar-fs");
const createMutex = require("./createMutex");
function createTempPath(name, version) {
const normalName = name.replace(/\//g, "-")
return path.join(tmpdir(), `unpkg-${normalName}-${version}`)
const normalName = name.replace(/\//g, "-");
return path.join(tmpdir(), `unpkg-${normalName}-${version}`);
}
function stripNamePrefix(headers) {
@ -17,12 +17,12 @@ function stripNamePrefix(headers) {
// so we shorten that to just "index.js" here. A few packages use a
// prefix other than "package/". e.g. the firebase package uses the
// "firebase_npm/" prefix. So we just strip the first dir name.
headers.name = headers.name.replace(/^[^/]+\//, "")
return headers
headers.name = headers.name.replace(/^[^/]+\//, "");
return headers;
}
function ignoreSymlinks(file, headers) {
return headers.type === "link"
return headers.type === "link";
}
function extractResponse(response, outputDir) {
@ -31,26 +31,26 @@ function extractResponse(response, outputDir) {
readable: true, // All dirs/files should be readable.
map: stripNamePrefix,
ignore: ignoreSymlinks
})
});
response.body
.pipe(gunzip())
.pipe(extract)
.on("finish", resolve)
.on("error", reject)
})
.on("error", reject);
});
}
function fetchAndExtract(tarballURL, outputDir) {
console.log(`info: Fetching ${tarballURL} and extracting to ${outputDir}`)
console.log(`info: Fetching ${tarballURL} and extracting to ${outputDir}`);
return fetch(tarballURL).then(response => {
return extractResponse(response, outputDir)
})
return extractResponse(response, outputDir);
});
}
const fetchMutex = createMutex((payload, callback) => {
const { tarballURL, outputDir } = payload
const { tarballURL, outputDir } = payload;
fs.access(outputDir, function(error) {
if (error) {
@ -59,30 +59,30 @@ const fetchMutex = createMutex((payload, callback) => {
// fetched a package for the first time. Carry on!
mkdirp(outputDir, function(error) {
if (error) {
callback(error)
callback(error);
} else {
fetchAndExtract(tarballURL, outputDir).then(() => {
callback()
}, callback)
callback();
}, callback);
}
})
});
} else {
callback(error)
callback(error);
}
} else {
// Best case: we already have this package cached on disk!
callback()
callback();
}
})
})
});
});
function getPackage(packageConfig, callback) {
const tarballURL = packageConfig.dist.tarball
const outputDir = createTempPath(packageConfig.name, packageConfig.version)
const tarballURL = packageConfig.dist.tarball;
const outputDir = createTempPath(packageConfig.name, packageConfig.version);
fetchMutex(tarballURL, { tarballURL, outputDir }, function(error) {
callback(error, outputDir)
})
callback(error, outputDir);
});
}
module.exports = getPackage
module.exports = getPackage;

View File

@ -1,33 +1,34 @@
require("isomorphic-fetch")
const createCache = require("./createCache")
const createMutex = require("./createMutex")
require("isomorphic-fetch");
const createCache = require("./createCache");
const createMutex = require("./createMutex");
const RegistryURL = process.env.NPM_REGISTRY_URL || "https://registry.npmjs.org"
const RegistryURL =
process.env.NPM_REGISTRY_URL || "https://registry.npmjs.org";
const PackageInfoCache = createCache("packageInfo")
const PackageInfoCache = createCache("packageInfo");
function fetchPackageInfo(packageName) {
console.log(`info: Fetching package info for ${packageName}`)
console.log(`info: Fetching package info for ${packageName}`);
let encodedPackageName
let encodedPackageName;
if (packageName.charAt(0) === "@") {
encodedPackageName = `@${encodeURIComponent(packageName.substring(1))}`
encodedPackageName = `@${encodeURIComponent(packageName.substring(1))}`;
} else {
encodedPackageName = encodeURIComponent(packageName)
encodedPackageName = encodeURIComponent(packageName);
}
const url = `${RegistryURL}/${encodedPackageName}`
const url = `${RegistryURL}/${encodedPackageName}`;
return fetch(url, {
headers: {
Accept: "application/json"
}
}).then(res => {
return res.status === 404 ? null : res.json()
})
return res.status === 404 ? null : res.json();
});
}
const PackageNotFound = "PackageNotFound"
const PackageNotFound = "PackageNotFound";
// This mutex prevents multiple concurrent requests to
// the registry for the same package info.
@ -40,32 +41,32 @@ const fetchMutex = createMutex((packageName, callback) => {
// In the worst case, a brand new package's info will be
// available within 5 minutes.
PackageInfoCache.set(packageName, PackageNotFound, 300, function() {
callback(null, value)
})
callback(null, value);
});
} else {
// Cache valid package info for 1 minute.
PackageInfoCache.set(packageName, value, 60, function() {
callback(null, value)
})
callback(null, value);
});
}
},
function(error) {
// Do not cache errors.
PackageInfoCache.del(packageName, function() {
callback(error)
})
callback(error);
});
}
)
})
);
});
function getPackageInfo(packageName, callback) {
PackageInfoCache.get(packageName, function(error, value) {
if (error || value != null) {
callback(error, value === PackageNotFound ? null : value)
callback(error, value === PackageNotFound ? null : value);
} else {
fetchMutex(packageName, packageName, callback)
fetchMutex(packageName, packageName, callback);
}
})
});
}
module.exports = getPackageInfo
module.exports = getPackageInfo;

View File

@ -1,15 +1,15 @@
const db = require("../../RedisClient")
const db = require("../../RedisClient");
function incrementCounter(counter, key, by) {
return new Promise((resolve, reject) => {
db.hincrby(counter, key, by, (error, value) => {
if (error) {
reject(error)
reject(error);
} else {
resolve(value)
resolve(value);
}
})
})
});
});
}
module.exports = incrementCounter
module.exports = incrementCounter;

View File

@ -1,25 +1,25 @@
const parsePackageURL = require("../utils/parsePackageURL")
const parsePackageURL = require("../utils/parsePackageURL");
/**
* Adds various properties to the request object to do with the
* package/file being requested.
*/
function validatePackageURL(req, res, next) {
const url = parsePackageURL(req.url)
const url = parsePackageURL(req.url);
if (url == null) {
return res.status(403).send({ error: `Invalid URL: ${req.url}` })
return res.status(403).send({ error: `Invalid URL: ${req.url}` });
}
req.packageName = url.packageName
req.packageVersion = url.packageVersion
req.packageSpec = `${url.packageName}@${url.packageVersion}`
req.pathname = url.pathname
req.filename = url.filename
req.search = url.search
req.query = url.query
req.packageName = url.packageName;
req.packageVersion = url.packageVersion;
req.packageSpec = `${url.packageName}@${url.packageVersion}`;
req.pathname = url.pathname;
req.filename = url.filename;
req.search = url.search;
req.query = url.query;
next()
next();
}
module.exports = validatePackageURL
module.exports = validatePackageURL;