Published
Edited
Feb 4, 2022
1 fork
Importers
8 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
api = {
const api = Router();
api.use((req, res, next) => {
const cookieHandler = cookieParser(req.context.secrets['endpointservices_secretadmin_service_account_key'])
cookieHandler(req, res, next)
});
api.post('/signin', signinHandler);
api.post('/check', checkHandler);
api.post('/signout', signoutHandler);
return api
}
Insert cell
Insert cell
Insert cell
signinHandler = async (req, res) => {
res.header('Access-Control-Allow-Origin', 'https://endpointservices.static.observableusercontent.com')
res.header('Access-Control-Allow-Credentials', 'true')
try {
const jwt = await checkToken(req.body);
res.cookie('endpointservicesuser',
jwt.uid /* Firebase id */, {
maxAge: 30 * 24 * 60 * 60 * 1000, // 30 day expiry
httpOnly: true, // Not availible in JS env
secure: true, // Https only
signed: true, // Encrypted
path: '/notebooks/@endpointservices/login', // Prevent access from other notebooks
sameSite: 'None'
});
res.status(200).end();
} catch (err) {
const msg = err.message;
console.error(msg);
res.status(403).send(msg);
}
}
Insert cell
Insert cell
checkHandler = async (req, res) => {
res.header('Access-Control-Allow-Origin', req.headers.origin)
res.header('Access-Control-Allow-Credentials', 'true')
if (req.signedCookies && req.signedCookies.endpointservicesuser) {
const uid = req.signedCookies.endpointservicesuser;
const sa = JSON.parse(req.context.secrets['endpointservices_secretadmin_service_account_key']);
const access_token = await getAccessTokenFromServiceAccount(sa);
await signinWithAccessToken(firebase, access_token)
if (req.headers.origin === "https://endpointservices.static.observableusercontent.com" || await isOwner(uid, subdomain(req.headers.origin))) {
console.log(`Minting ${uid} from ${subdomain(req.headers.origin)}`)
res.send(await createCustomToken(sa, uid));
} else {
// Signin token present but user is calling from an origin that is not allowed federation
res.status(403).end()
}
} else {
res.status(401).end() // No signin token present
}
}
Insert cell
Insert cell
signoutHandler = async (req, res) => {
res.header('Access-Control-Allow-Origin', req.headers.origin)
res.header('Access-Control-Allow-Credentials', 'true')
try {
res.clearCookie('endpointservicesuser', {
httpOnly: true, // Not availible in JS env
secure: true, // Https only
signed: true, // Encrypted
path: '/notebooks/@endpointservices/login', // Prevent access from other notebooks
sameSite: 'None'
});
res.status(200).end();
} catch (err) {
const msg = err.message;
console.error(msg);
res.status(500).send(msg);
}
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more