Keystonejs: change admin UI login screen message - javascript

Keystonejs has some kind of bug on the Admin UI login page:
While trying to access Keystone Admin UI, with User that Permissions isAdmin = false
In case login/pass is correct Keystonejs screen says: "You're already signed in."
There should be response something like: "You don't have permissions"
It's no too informative so I suggest to change it to something like "You don't have permissions".
So question: is it possible to change text of that message?

The issue is that you have logged in using valid credentials but have not granted that user access to the Admin UI. There is (as at Keystone 4.0.0) no default path for users without the canAccessKeystone permission. I believe the general assumption was that non-admin users should not be logging into Keystone admin, but authenticated sessions are still useful for API endpoints.
So question: is it possible to change text of that message?
I'm not aware of a straightforward way to only change this message, but if you're keen you could always modify the Keystone 4.0 source for your own requirements and submit a pull request to have this considered for merging into the project. I've created issue #4786 in Keystone's GitHub issue tracker to improve the messaging for users who successfully login but do not have access to the admin UI.
In the interim, one possible workaround would be to use the keystone signin redirect configuration to set a preferred entry point that can either handle all user types or redirect appropriately.
For example, you could add the following to your keystone.js config:
keystone.set('signin redirect', '/gohome')
The /gohome route could render a page or do a simple redirection based on user properties:
app.get('/gohome', function(req, res) {
var url = (req.user && req.user.canAccessKeystone) ? '/keystone' : '/user';
res.redirect(url);
});

Related

ArcGIS JavaScript API: How to show company specific portal login screen when trying to access secure layer

I have written a webapp with the ArcGIS JavaScript API and all is working fine. Now I am trying to add secured layers to the web app and the app starts asking for credentials via a default login screen. I could use that, just entering username and password, but most users don't know their user name and password for ArcGIS.
The company has implemented SSO with ArcGIS so users don't have to fill in their credentials. Users typically go to the main company.maps.arcgis.com site and get to a company specific login screen where they have the option to click this SSO button.
My question; how can I make the JavaScript API show this company specific login page with SSO button instead of the default one?
I tried registering oauthInfo and serverInfo setting but without success.
Did anybody else ever built this?
The SSO sign in prompt should occur as long as you're using OAuthInfo and registering it with the IdentityManager. You'll have to make sure that you:
Add and register an application in the organization where
the data is coming from. The redirect URI should point to the server
that's hosting the application URL.
Get the Client ID from the registered application and add it to the appId in OAuthInfo along with the portalUrl property (which should be https://company.maps.arcgis.com)
Set the popup property to false.
Verify all the data is coming from the same organization. If it's not, then you may get another prompt since it's not registered with the IdentityManager.
Here's an example of what the OAuthInfo should look like:
const info = new OAuthInfo({
// Swap this ID out with registered application ID
appId: "APPID",
portalUrl: "https://company.maps.arcgis.com/",
flowType: "auto", // default that uses two-step flow
popup: false,
});
esriId.registerOAuthInfos([info]);

How to configure security to allow swagger url to be accessed only with authentication in nodejs

I have integrated swagger in node and it is accessible on http://localhost:3002/api-docs. But the swagger ui is publicly accessible. I want to add authentication/security to access this route. When user hits http://localhost:3002/api-docs, it should show popup/prompt to enter username/password. If username and password is correct then only user should able to see swagger UI.
Possibly like as seen in below screenshot
I am using swagger-ui-express, and this is my code that I m using
import swaggerUi from 'swagger-ui-express';
import * as swaggerDocument from './swagger.json'
....
....
app.use("/api-docs",swaggerUi.serve,swaggerUi.setup(swaggerDocument));
I searched on the internet but didn't got any solution. I found one solution but that is in spring.
Thanks in advance !!
You can plug in a basic-auth middleware (e.g. https://github.com/LionC/express-basic-auth) to protect the swagger-ui route. If you use express-basic-auth, make sure to set the challenge option in order to force the browser to open a prompt:
const basicAuth = require('express-basic-auth');
app.use("/api-docs",basicAuth({
users: {'yourUser': 'yourPassword'},
challenge: true,
}), swaggerUi.serve, swaggerUi.setup(swaggerDocument));

How can we separate route of admin and user?

I am creating routes in node js . I am creating routes for dashboard.
User login and get the JWT token.
By sending Token,User can access some route related to user(edit,delete,logout route etc).
But For admin, I want to create the routes which can see the list of users,edit or remove users,check the logout time of users.I have also set the flag in table to identify the person is user or Admin.
How will be authenticate routes for Admins on backend side?
You can be inspired by this logic, And no further explanation can be given here. follow steps (It may help):
First) define role field into DB mongoDB or Mysql (for example):
enum: ['user', 'admin']
Second) create a function checkRole(role) for check role after signin and verify jwt, then get user
Third) create separate route for admin panel (for example):
router.route('/admin-panel').use(authController.checkRole('admin'))
You can put your authorization flag in your JWT. When a user logs in, your server generates corresponding JWT, in which included authentication info(i.e. userId). You can put additional authorization info in the token(i.e. auth).
Based on the auth field, your server can identify whether the request is sent by a general user or an admin. Of course, securing the JWT from hijacking is an another story.

Sending ID token to signInSuccessUrl in firebaseui

I'm using firebaseUI to sign in users to my web app. I am using the redirect option. Upon successful sign in, the users are redirected to signInSuccessUrl, which is the admin page of my web app. However, I want to be able to pass the ID token associated with the user to the admin endpoint, where it can be authenticated and checked whether the user trying to log in has admin permissions or not (this I do by checking the user permissions in my database).
I've considered a few other options, namely:
Using firebase.auth().onAuthStateChanged on the admin page itself, checking if the user is signed in, and making a request to the backend to check if the user is an admin. If these conditions are met, render the page, otherwise, show permission denied.
The problem with this approach is that:
It moves a significant part of the auth to the client side
I can't restrict access at the endpoint level itself. In contrast, if I send an ID token, I can check if the user is an admin or not and accordingly decide what to render, instead of always rendering the admin page and then checking on the client side if the user is logged in and is an admin.
Making a dummy page in between the firebase sign-in page and the admin home page. This dummy page would check if the user is signed in using onAuthStateChanged as mentioned above, make a request to the backend to check if the user has admin permissions, and based on the results, redirect to either the admin home page or show permission denied and go back to the login page.
This is how the config would look like if I do this:
var uiConfig = {
signInSuccessUrl: '/admintestpage/',
signInOptions: [
firebase.auth.GoogleAuthProvider.PROVIDER_ID
]
}
The /admintestpage/ endpoint would render test.html, which would have code something like:
<script type="text/javascript">
initApp = function() {
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
idToken = user.getIdToken();
/*Send idToken to a backend api to check if the corresponding user is an admin*/
/*redirect to https://my-app.com/adminpage/ if user is an admin, otherwise, redirect to https://my-app.com/login/ */
} else {
/*user is signed-off, redirect to https://my-app.com/login */
}
}
</script>
I'm keeping this as the last option as it doesn't look like a very good flow.
Here's how my uiConfig looks right now:
var uiConfig = {
signInSuccessUrl: '/adminpage/',
signInOptions: [
firebase.auth.GoogleAuthProvider.PROVIDER_ID
]
}
The Crux is that I want to render my admin home page only if I know beforehand that the user is logged in and is an admin.
I want to know if there is a way to pass the ID token as a basic auth header when redirecting to the signInSuccessUrl from the firebaseUI page, or if the idea of sending an ID token itself is not necessary and there is an alternate better flow.
I think you're on the right track. I've been struggling to find something elegant to do this as well, but I ended up doing what you did. Ideally I wish signInSuccessUrl passed the jwt payload, therefore, my backend server could verify its authenticity, and I can then look up the user and then set the session or reject the session.
A lot of the API's and docs are written in the context of a "Firebase first" or "Firebase only" so you have to start getting creative integrating with a traditional REST API.
My context is somewhat similar. I'm a mobile-only app that used Firebase auth to offload auth, in exchange, it then linked to my own custom token. Recently I needed to make a few web properties and wanted to implement this same exchange for my own session management in a traditional client/server synchronous REST page.
window.initApp = function() {
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
// User is signed in.
user.getIdToken().then(function(accessToken) {
redirectPost("/login", {"access_token": accessToken, "authenticity_token": $("meta[name='csrf-token']").attr('content')})
});
} else {
// User is signed out.
}
}, function(error) {
console.log(error);
});
};

How to implement username/password auth with express ntlm?

I am trying to implement username and password auth with Express-ntlm.I have added below code as middleware
app.use( ntlm({
domain: '<domainname>',
domaincontroller: '<ldap url>',
}));
I am not providing any user name password in the request and its automatically adding ntlm header in the request with my loggedin user details. I am getting {Authenticated:true} along with my username and system name in request.ntlm.
How can I provide different username/password in this and authenticate?
Also will this work if I login from linux/mac system?
If you use a supported browser (e.g. IE) NTLM will automatically log the user in using the current session in Windows. express-ntlm will just receive this information and exposes it to the application.
If you want to use other credentials you have to log in using a different user in Windows or use a browser that will show you a prompt for username and password if it gets an NTLM challenge. If I remember correctly Chrome will do it like this.
I never tried it using macOS/Linux, but I'm sure most browser will just provide you a username/password prompt.

Categories