Add an onboarding check and redirect to lead people to onboarding after signing up

Add skip onboarding button that redirects to account
Remove some unnecessary data from accountsjson call
develop
Thomas Lynch 10 months ago
parent 64a4aafff8
commit 1ae3b2df05
  1. 3
      api.js
  2. 28
      controllers/account.js
  3. 4
      controllers/domains.js
  4. 4
      healthcheck/worker.js
  5. 4
      pages/account.js
  6. 4
      pages/certs.js
  7. 4
      pages/clusters.js
  8. 6
      pages/csr.js
  9. 4
      pages/map/[name].js
  10. 9
      pages/onboarding.js
  11. 19
      router.js
  12. 2
      templates.js

@ -4,6 +4,9 @@ import NProgress from 'nprogress';
export async function getAccount(dispatch, errorCallback, router) {
return ApiCall('/account.json', 'GET', null, dispatch, errorCallback, router);
}
export async function finishOnboarding(dispatch, errorCallback, router) {
return ApiCall('/forms/onboarding', 'POST', null, dispatch, errorCallback, router);
}
export async function login(body, dispatch, errorCallback, router) {
return ApiCall('/forms/login', 'POST', body, dispatch, errorCallback, router);
}

@ -11,8 +11,6 @@ resolver.setServers(process.env.NAMESERVERS.split(','));
exports.accountData = async (req, res, _next) => {
let maps = []
, globalAcl
, aRecords = []
, aaaaRecords = []
, txtRecords = [];
if (res.locals.user.clusters.length > 0) {
maps = res.locals.dataPlane
@ -24,17 +22,13 @@ exports.accountData = async (req, res, _next) => {
globalAcl = res.locals.dataPlane
.getOneRuntimeMap('ddos_global')
.then(res => res.data.description.split('').reverse()[0]);
aRecords = resolver.resolve(process.env.ALL_IP_DOMAIN, 'A');
aaaaRecords = resolver.resolve(process.env.ALL_IP_DOMAIN, 'AAAA');
txtRecords = resolver.resolve(process.env.NAMESERVER_TXT_DOMAIN, 'TXT');
}
([maps, globalAcl, aRecords, aaaaRecords, txtRecords] = await Promise.all([maps, globalAcl, aRecords, aaaaRecords, txtRecords]));
([maps, globalAcl, txtRecords] = await Promise.all([maps, globalAcl, txtRecords]));
return {
csrf: req.csrfToken(),
maps,
globalAcl: globalAcl === '1',
aRecords,
aaaaRecords,
txtRecords,
};
};
@ -177,6 +171,7 @@ exports.register = async (req, res) => {
domains: [],
clusters: process.env.DEFAULT_CLUSTER ? [process.env.DEFAULT_CLUSTER] : [],
activeCluster: 0,
onboarding: false,
});
return dynamicResponse(req, res, 302, { redirect: '/login' });
@ -191,3 +186,22 @@ exports.logout = (req, res) => {
req.session.destroy();
return dynamicResponse(req, res, 302, { redirect: '/login' });
};
/**
* POST /forms/onboarding
* finish/skip onboarding
*/
exports.finishOnboarding = async (req, res) => {
if (!res.locals.user) {
return dynamicResponse(req, res, 400, { error: 'Bad request' });
}
await db.db.collection('accounts')
.updateOne({
_id: res.locals.user.username
}, {
'$set': {
onboarding: true,
}
});
return dynamicResponse(req, res, 302, { redirect: '/account' });
};

@ -67,6 +67,10 @@ exports.addDomain = async (req, res, next) => {
return dynamicResponse(req, res, 400, { error: 'Invalid input' });
}
if (res.locals.user.username !== "admin" && res.locals.user.domains && res.locals.user.domains.length >= 10) {
return dynamicResponse(req, res, 403, { error: 'Domain limit reached' });
}
let domain = req.body.domain.toLowerCase();
try {

@ -48,7 +48,7 @@ async function doCheck(domainKey, hkey, record) {
const host = isIPv4(record.ip) ? record.ip : `[${record.ip}]`;
const hostHeader = domainKey.substring(4, domainKey.length-1);
//await fetch(`https://${host}/.basedflare/cgi/trace`, {
await fetch(`https://${host}/`, {
await fetch(`https://${host}/.basedflare/cgi/ping`, {
method: 'HEAD',
redirect: 'manual',
headers: { 'Host': hostHeader },
@ -59,7 +59,7 @@ async function doCheck(domainKey, hkey, record) {
} catch(e) {
if (e && e.cause && e.cause.code && e.cause.code === 'ERR_TLS_CERT_ALTNAME_INVALID') {
//invalid cert doesn't mean the server is dead
console.warn('health check ERR_TLS_CERT_ALTNAME_INVALID for', domainKey, hkey, record.ip);
console.info('health check ERR_TLS_CERT_ALTNAME_INVALID for', domainKey, hkey, record.ip);
recordHealth = '1';
} else {
console.warn(e)

@ -33,6 +33,10 @@ export default function Account(props) {
const { user, maps, globalAcl, csrf } = state;
if (user && !user.onboarding) {
router.push('/onboarding');
}
const isAdmin = user.username === 'admin';
// Next cluster number for > browse button

@ -33,6 +33,10 @@ export default function Certs(props) {
const { user, csrf, dbCerts, clusterCerts } = state;
if (user && !user.onboarding) {
router.push('/onboarding');
}
async function addCert(e) {
e.preventDefault();
try {

@ -33,6 +33,10 @@ export default function Clusters(props) {
const { user, csrf } = state;
if (user && !user.onboarding) {
router.push('/onboarding');
}
async function addCluster(e) {
e.preventDefault();
setError(null);

@ -30,7 +30,11 @@ export default function Csr(props) {
);
}
const { csrf } = state;
const { user, csrf } = state;
if (user && !user.onboarding) {
router.push('/onboarding');
}
return (
<>

@ -35,6 +35,10 @@ const MapPage = (props) => {
const { user, mapValueNames, mapInfo, map, csrf, showValues } = state;
if (user && !user.onboarding) {
router.push('/onboarding');
}
async function addToMap(e) {
e.preventDefault();
await API.addToMap(mapInfo.name, {

@ -36,6 +36,11 @@ export default function Onboarding(props) {
const backendAdded = backendMap && backendMap.count > 0;
const certAdded = user.numCerts > 0;
async function finishOnboarding(e) {
await API.finishOnboarding(dispatch, setError, router);
await API.getAccount(dispatch, setError, router);
}
async function addDomain(e) {
e.preventDefault();
await API.addDomain({ _csrf: csrf, domain: e.target.domain.value, onboarding: e.target.onboarding.value }, dispatch, setError, router);
@ -72,6 +77,10 @@ export default function Onboarding(props) {
<h5 className="fw-bold">Onboarding</h5>
{!user.onboarding && <div className="my-2">
<input onClick={finishOnboarding} className="btn btn-warning" type="submit" value="Skip Onboarding" />
</div>}
<div className="list-group">
<div className="list-group-item d-flex gap-3">
<input className="form-check-input flex-shrink-0" type="checkbox" value="" checked={domainAdded} disabled />

@ -56,6 +56,7 @@ const testRouter = (server, app) => {
domains: account.domains,
clusters: strippedClusters,
activeCluster: account.activeCluster,
onboarding: account.onboarding,
numCerts,
};
return next();
@ -72,6 +73,13 @@ const testRouter = (server, app) => {
next();
};
const checkOnboarding = (req, res, next) => {
if (!res.locals.user || res.locals.user.onboarding === false) {
return dynamicResponse(req, res, 302, { redirect: '/onboarding' });
}
next();
};
const csrfMiddleware = csrf();
//dataplaneapi middleware
@ -148,8 +156,9 @@ const testRouter = (server, app) => {
server.get('/login', useSession, fetchSession, (req, res, next) => { return app.render(req, res, '/login') });
server.get('/register', useSession, fetchSession, (req, res, next) => { return app.render(req, res, '/register') });
//register/login/logout forms
//register/login/logout/onboarding forms
server.post('/forms/login', useSession, accountController.login);
server.post('/forms/onboarding', useSession, fetchSession, checkSession, accountController.finishOnboarding);
server.post('/forms/logout', useSession, accountController.logout);
server.post('/forms/register', useSession, fetchSession, accountController.register);
@ -158,12 +167,12 @@ const testRouter = (server, app) => {
, mapNamesOrString = mapNames.join('|');
//authed pages
server.get('/account', useSession, fetchSession, checkSession, useHaproxy, csrfMiddleware, accountController.accountPage.bind(null, app));
server.get('/account', useSession, fetchSession, checkSession, checkOnboarding, useHaproxy, csrfMiddleware, accountController.accountPage.bind(null, app));
server.get('/onboarding', useSession, fetchSession, checkSession, useHaproxy, csrfMiddleware, accountController.onboardingPage.bind(null, app));
server.get('/account.json', useSession, fetchSession, checkSession, useHaproxy, csrfMiddleware, accountController.accountJson);
server.get(`/map/:name(${mapNamesOrString})`, useSession, fetchSession, checkSession, useHaproxy, hasCluster, csrfMiddleware, mapsController.mapPage.bind(null, app));
server.get(`/map/:name(${mapNamesOrString})`, useSession, fetchSession, checkSession, checkOnboarding, useHaproxy, hasCluster, csrfMiddleware, mapsController.mapPage.bind(null, app));
server.get(`/map/:name(${mapNamesOrString}).json`, useSession, fetchSession, checkSession, useHaproxy, hasCluster, csrfMiddleware, mapsController.mapJson);
server.get('/clusters', useSession, fetchSession, checkSession, csrfMiddleware, clustersController.clustersPage.bind(null, app));
server.get('/clusters', useSession, fetchSession, checkSession, checkOnboarding, csrfMiddleware, clustersController.clustersPage.bind(null, app));
server.get('/clusters.json', useSession, fetchSession, checkSession, csrfMiddleware, clustersController.clustersJson);
server.get('/domains', useSession, fetchSession, checkSession, csrfMiddleware, domainsController.domainsPage.bind(null, app));
server.get('/domains.json', useSession, fetchSession, checkSession, csrfMiddleware, domainsController.domainsJson);
@ -172,7 +181,7 @@ const testRouter = (server, app) => {
server.get('/dns/:domain([a-zA-Z0-9-\.]+)', useSession, fetchSession, checkSession, csrfMiddleware, dnsController.dnsDomainPage.bind(null, app));
server.get('/dns/:domain([a-zA-Z0-9-\.]+)/:zone([a-zA-Z0-9-\.@_]+)/:type([a-z]+).json', useSession, fetchSession, checkSession, csrfMiddleware, dnsController.dnsRecordJson);
server.get('/dns/:domain([a-zA-Z0-9-\.]+)/:zone([a-zA-Z0-9-\.@_]+)/:type([a-z]+)', useSession, fetchSession, checkSession, csrfMiddleware, dnsController.dnsRecordPage.bind(null, app));
server.get('/certs', useSession, fetchSession, checkSession, useHaproxy, csrfMiddleware, certsController.certsPage.bind(null, app));
server.get('/certs', useSession, fetchSession, checkSession, checkOnboarding, useHaproxy, csrfMiddleware, certsController.certsPage.bind(null, app));
server.get('/certs.json', useSession, fetchSession, checkSession, useHaproxy, csrfMiddleware, certsController.certsJson);
// server.get('/stats', useSession, fetchSession, checkSession, useHaproxy, csrfMiddleware, accountController.statsPage.bind(null, app));
// server.get('/stats.json', useSession, fetchSession, checkSession, useHaproxy, csrfMiddleware, accountController.statsJson);

@ -38,5 +38,3 @@ exports.nsTemplate = () => Object.seal(Object.freeze(Object.preventExtensions([
"t": true
}
])));

Loading…
Cancel
Save