Changed how paths are handled by server.js, to more closely match the Angular

dev environment. New paths:

/api/login: redirects to SSO
/api: all calls (other than above) are sent to cloudapi
/: static content served from static/

All API calls to cloudapi now pass through server.js's HTTP /api, not /.

The static/static path is now gone, since it was causing too much trouble.
static/ is now a symlink directly to app/dist, which is where a fresh Angular
build appears when app/ is built.
This commit is contained in:
Marsell Kukuljevic 2021-04-10 21:14:09 +02:00
parent 18d35b5172
commit 8672439358
5 changed files with 39 additions and 41 deletions

View File

@ -25,46 +25,39 @@ The SSH key used must be the correct format, e.g. generated with:
# Endpoints # Endpoints
## GET /static/* ## GET /*
This is where all the front-end code goes. All files will be served as-is as This is where all the front-end code goes. All files will be served as-is as
found in that directory. The default is static/index.html. There is no found in that directory (by default a symlink to app/dist). The default is
authentication; all files are public. static/index.html. There is no authentication; all files are public.
## GET /login ## GET /api/login
Call this endpoint to begin the login cycle. It will redirect you to the SSO Call this endpoint to begin the login cycle. It will redirect you to the SSO
login page: an HTTP 302, with a Location header. login page: an HTTP 302, with a Location header.
## GET /token ## GET/POST/PUT/DELETE/HEAD /api/*
Upon successful login, the SSO login page will redirect to this endpoint. This All calls will be passed through to cloudapi. For these calls to succeed,
endpoint will return a 204, along with a X-Auth-Token header that must be saved they MUST provide an X-Auth-Token header, containing the token returned from
by the front-end code. All subsequent calls should provide this X-Auth-Token SSO.
header.
## Other
All other calls will be passed through to cloudapi. For these calls to succeed,
they MUST provide the X-Auth-Token header that the /token endpoint returns.
# Interaction cycle # Interaction cycle
client --- GET /login --------> this server client --- GET /api/login --------> this server
<-- 302 Location #1 ---- <-- 302 Location #1 ----
client --- GET <Location #1> --> SSO server client --- GET <Location #1> --> SSO server
<separate SSO cycle> <separate SSO cycle>
<-- 302 Location #2 ---- <-- 302 with token query arg
client --- GET <Location #2> --> this server
<-- 204 X-Auth-Token ----
From now on call this server as if it were a cloudapi server (using [cloudapi From now on call this server as if it were a cloudapi server (using [cloudapi
paths](https://github.com/joyent/sdc-cloudapi/blob/master/docs/index.md#api-introduction)), paths](https://github.com/joyent/sdc-cloudapi/blob/master/docs/index.md#api-introduction)),
always providing the X-Auth-Token. For example, to retrieve a list of packages: except prefixing any path with "/api". Also always provide the X-Auth-Token.
client --- GET /my/packages --> this server For example, to retrieve a list of packages:
client --- GET /api/my/packages --> this server
<-- 200 JSON body ------ <-- 200 JSON body ------
The most useful cloudapi endpoints to begin with will be ListPackages, The most useful cloudapi endpoints to begin with will be ListPackages,

View File

@ -15,6 +15,10 @@ let CLOUDAPI = {};
let CLOUDAPI_HOST = ''; let CLOUDAPI_HOST = '';
let SIGNER = {}; let SIGNER = {};
const LOGIN_PATH = '/api/login';
const API_PATH = '/api'; // all calls here go to cloudapi
const API_RE = new RegExp('^' + API_PATH + '/');
const STATIC_RE = new RegExp('^/');
// Take any HTTP request that has a token, sign that request with an // Take any HTTP request that has a token, sign that request with an
// HTTP-Signature header, and pass it along to cloudapi. Return any response // HTTP-Signature header, and pass it along to cloudapi. Return any response
@ -40,16 +44,19 @@ function proxy(req, res, cb) {
// check the X-Auth-Token is present // check the X-Auth-Token is present
if (req.header('X-Auth-Token') == undefined) { if (req.header('X-Auth-Token') == undefined) {
res.send({"Error": "X-Auth-Token header missing"}); res.send({'Error': 'X-Auth-Token header missing'});
res.send(401); res.send(401);
return cb(); return cb();
} }
// strip off /api from path before forwarding to cloudapi
let url = req.url.substr(API_PATH.length);
// sign the request before forwarding to cloudapi // sign the request before forwarding to cloudapi
let headers = req.headers; let headers = req.headers;
var rs = mod_sdcauth.requestSigner({ sign: SIGNER }); var rs = mod_sdcauth.requestSigner({ sign: SIGNER });
headers.date = rs.writeDateHeader(); headers.date = rs.writeDateHeader();
rs.writeTarget(req.method, req.url); rs.writeTarget(req.method, url);
rs.sign(function signedCb(err, authz) { rs.sign(function signedCb(err, authz) {
if (err) { if (err) {
@ -60,10 +67,12 @@ function proxy(req, res, cb) {
headers.authorization = authz; headers.authorization = authz;
const opts = { const opts = {
path: req.url, path: url,
headers: headers headers: headers
}; };
console.dir(opts);
// make the call to cloudapi // make the call to cloudapi
switch (req.method) { switch (req.method) {
case 'GET': CLOUDAPI.get(opts, proxyReturn); break; case 'GET': CLOUDAPI.get(opts, proxyReturn); break;
@ -153,20 +162,21 @@ function main() {
server.use(mod_restify.authorizationParser()); server.use(mod_restify.authorizationParser());
server.use(mod_restify.bodyReader()); server.use(mod_restify.bodyReader());
// where to server static content from // login path is /api/login
server.get(/^\/static.*/, mod_restify.plugins.serveStatic({ server.get(LOGIN_PATH, login);
// all cloudapi calls are proxied through /api
server.get(API_RE, proxy);
server.put(API_RE, proxy);
server.del(API_RE, proxy);
server.post(API_RE, proxy);
server.head(API_RE, proxy);
// where to serve static content from
server.get(STATIC_RE, mod_restify.plugins.serveStatic({
directory: 'static', directory: 'static',
default: 'index.html' default: 'index.html'
})); }));
// route HTTP requests to proper functions
server.get('/login', login);
server.get(/^/, proxy);
server.put(/^/, proxy);
server.del(/^/, proxy);
server.post(/^/, proxy);
server.head(/^/, proxy);
// enable HTTP server // enable HTTP server
server.listen(CONFIG.server.port, function listening() { server.listen(CONFIG.server.port, function listening() {

1
static Symbolic link
View File

@ -0,0 +1 @@
app/dist

View File

@ -1,5 +0,0 @@
<html>
<body>
Hi!
</body>
</html>

View File

@ -1 +0,0 @@
.