I am using glue to spin up the hapi server so I gave the json object with connection and registration details.
I have 10 routes and i need to use authentication strategy for all the 10 routes, So followed the below steps
1) I have registered the xyz custom auth plugin
2) Defined the strategy server.auth.strategy('xyz', 'xyz', { });
3) At every route level I am enabling auth strategy
auth: {
strategies: ['xyz'],
}
How can I give below line to glue configuration object itself.
server.auth.strategy('xyz', 'xyz', { });
Glue.compose(ServerConfig, { relativeTo: baseDir }, (err, server) => {
internals.server = server;
})
One more question here is, in this line server.auth.strategy('xyz', 'xyz', { from json file}); I am reading the JSON data from a config file. When I change the data in this JSON file I dont want to restart the server manually to load the modified data. Is there any plugin or custom code to achieve this?
I figured out a general workaround for when you want to do setup that Glue does not directly support (AFAIK) and you also don't want to keep adding to index.js.
Create a plugins folder where your manifest.js is located.
Create a file plugins/auth.js (in this case). Here you will have a register callback with access to the server object and you can make setup calls that go beyond what Glue does declaratively.
Add a plugin item to manifest.js pointing to your plugin file.
in manifest.js:
register: {
plugins: [
{
plugin: './plugins/auth',
},
]
}
in plugins/auth.js:
module.exports = {
name: 'auth',
async register (server) {
await server.register([
require('#hapi/cookie'),
]);
server.auth.strategy('session', 'cookie', {
cookie: {
name: 'sid-example',
password: '!wsYhFA*C2U6nz=Bu^%A#^F#SF3&kSR6',
isSecure: false
},
redirectTo: '/login',
validateFunc: async (request, session) => {
const account = await users.find(
(user) => (user.id === session.id)
);
if (!account) {
return { valid: false };
}
return { valid: true, credentials: account };
}
});
server.auth.default('session');
},
};
(auth setup code is from the Hapi docs at enter link description here)
This is the way I have found where I can call things like server.auth.strategy() sort-of from manifest.js.
Note: Auth is not a great example for this technique as there is a special folder for auth strategies in lib/auth/strategies.
Related
I'm trying to setup navigation guards in my Nuxt app to redirect users to the login screen if they are not authenticated via Firebase Authentication. When the user attempts to navigate my router middleware is redirecting them successfully, but on page load they are not being redirected.
I did realize that the middleware is not even being fired on page load. I found a recommendation to try a plugin to handle the redirect on page load, but it is not working. Calling router.push from within the plugin does not redirect the user.
Here are a few notes on my setup. This is being deployed to firebase hosting directly as a SPA with no SSR. It's using the Nuxt-Firebase module with Firebase Authentication service.
// nuxt.config.js
target: "server", // server here works when I deploy to firebase, but I also tried static
ssr: false,
middleware: ["auth"],
plugins: [
"~/plugins/auth.js",
],
modules: [
[
"#nuxtjs/firebase",
{
services: {
auth: {
initialize: {
onAuthStateChangedMutation:
"authData/ON_AUTH_STATE_CHANGED_MUTATION",
onAuthStateChangedAction: "authData/ON_AUTH_STATE_CHANGED_ACTION",
subscribeManually: false,
},
},
},
},
],
],
};
Here's a sample plugin I thought might solve this, but calling handleLoggedOut appears to do nothing on page load.
// --- plugin to redirect user --- /plugins/auth.js ---
export default function (context, inject) {
const auth = {
handleLoggedOut: () => {
console.log("logout handled");
context.redirect("/login");
},
};
inject("auth", auth);
}
// --- store actions --- /store/authData.js ---
actions: {
async ON_AUTH_STATE_CHANGED_ACTION(
{ commit, state, dispatch },
{ authUser, claims }
) {
if (authUser) {
// logged in
}
else {
// attempting to redirect here does not work
this.$auth.handleLoggedOut()
}
}
I'm new to Nuxt and I can't seem to find an example that solves my issue.
Any help would be greatly appreciated, thank you!
Code seems fine, But you can just use the this.$fire.auth.signOut() and you can remove the auth plugin.
Example:
// --- store actions --- /store/authData.js ---
actions: {
async signOut({ commit }, payload) {
try {
await this.$fire.auth.signOut();
// This is just a guard to avoid navigation guard error (NavigationDuplicated),
// you can remove the if block
if (!payload) {
this.$router.push('/login')
}
commit(ON_AUTH_STATE_CHANGED_MUTATION, { authUser: null})
} catch(err) {
console.log(err)
}
},
async ON_AUTH_STATE_CHANGED_ACTION(
{ commit, state, dispatch },
{ authUser, claims }
) {
if (authUser) {
// logged in
}
else {
// attempting to redirect here does not work
return dispatch('signOut')
}
}
}
The solution for redirecting users to the login on page load was to put this in my auth middleware:
export default function ({ redirect, store, route }) {
// https://nuxtjs.org/docs/internals-glossary/context#redirect
if (!store || !store.getters || !store.getters["authData/isLoggedIn"]) {
window.onNuxtReady(() => {
window.$nuxt.$router.push("/login");
});
}
}
we are using nuxt 2.14.12 and #nuxtjs/router 1.5.0
we are trying to use runtime config to make some HTTP request client side.
here is our router.js
export async function createRouter(ssrContext, createDefaultRouter) {
[...]
try {
const res = await axios.get(`${config.public.apiBaseUrl}/myslug`)
} catch (e) { }
[...]
}
here is the config file
[...]
const apiBaseUrl = `${process.env.NUXT_ENV_MY_API_URL || 'http://my-dev-domain.com'}`
[...]
export default {
apiBaseUrl,
},
private: {
apiBaseUrl,
},
[...]
here is our nuxt.config.js
export default {
[...]
publicRuntimeConfig: config.public,
privateRuntimeConfig: config.private,
[...]
buildModules: [
['#nuxtjs/router', { keepDefaultRouter: true }],
],
[...]
router: {
linkActiveClass: 'current-menu-item'
},
[...]
}
we use nuxt build in our CI and later at runtime we use nuxt start
at runtime, despite on server side the env variable NUXT_ENV_MY_API_URL is correctly set, on the client site the variable looks hardcoded (I think webpack replace it) and we get the value present on build time (http://my-dev-domain.com)
is there a way to use the runtime config on the client side?
thank you
I want to unit test a mixin.
So I need to create a loopback 3.x application completely in code.
It works so far and it registers my mixin, but it doesn't register my model.
It is not exposed over REST, but thats exactly what I need.
Here is my code:
// create loopback app
app = loopback();
app.use(loopback.rest());
// create data source
app.dataSource('db', {
name: 'db',
connector: loopback.Memory
});
app.loopback.modelBuilder.mixins.define('accesscheck', AccessCheck);
app.loopback.createModel({
name: 'AccesscheckTest',
plural: 'AccesscheckTests',
base: "PersistedModel",
accesscheck: [{
permission: "ALLOW",
roles: [
'admin'
],
accessScope: "organization",
method: "findById"
}],
mixins: [
"accesscheck"
]
});
var Accesscheck = app.loopback.getModel('Accesscheck');
app.model(Accesscheck, { dataSource: 'db', public: true });
// start server
var connection = app.listen(3000, () => {
if (done) {
done();
}
});
app.activeConnection = connection;
return app;
PS: I know that there is the ACL Model in loopback but it doesn't fit my need so I need to implement my own Accesscheck.
You need to call boot from loopback-boot.
I think it's better to require the server.js in test units.
And make config file for test in this pattern datasources.test.json and a script in package.json for test like this : "test": "NODE_ENV=test ./node_modules/mocha/bin/mocha --recursive",
So there is no need to create models in unit tests anymore.
I'm currently working on an app with a server that uses Hapi, and I am running into a problem whenever I try to load a .jade file. Here is the current code for my index.js file:
var Hapi = require('hapi');
var internals = {};
internals.main = function() {
var options = {
views: {
engines: { jade: 'jade' },
path: '../app',
compileOptions: {
pretty: true
}
}
};
this._server = new Hapi.createServer('localhost', 8000, options);
this._server.route({
method: 'GET',
path: '/',
handler: function(request, reply) {
reply.view('index')
}
});
// Start server.
this._server.start()
};
internals.main();
The file has a series of local scripts and CSS files that are in the app directory, but when the page index.jade is loaded, it does not see those local files. Is there something I need to add/modify in my options, or is this location of local scripts and style files a problem with jade compilation using Hapi?
I was looking for a similar solution, while trying to setup a single page application with angular.js and hapi.js
I have found that adding the configuration below to your server routes will help to make CSS, JS, ... files in '/public' directory visible to the application.
server.route({
method: "GET",
path: "/public/{path*}",
handler: {
directory: {
path: "./public",
listing: false,
index: false
}
}
});
Hope it helps.
https://github.com/davebryson/meteor_file_upload_example
the above is the original code using Meteor.router
and i wanted to convert this code only using iron-router, instead of previous router package
but the problem is when i upload file,
i can't understand how to convert these code using iron-router api.
i think there's a problem with index.html and serverside main.js code but i can't fix that.
would you please convert this code below using iron router plz?
in serverside main.js in the original code.
Meteor.Router.configure(
{
bodyParser:
{
uploadDir: 'uploads',
hash: 'sha1',
keepExtensions : true
}
}
);
Meteor.Router.add('/upload/file', 'POST',
function()
{
var title = this.request.body.fileTitle,
size = this.request.files.fileInfo.size,
path = this.request.files.fileInfo.path,
name = this.request.files.fileInfo.name,
obj = {title: title, size: size, path: path, name: name};
Files.insert(obj);
// redirect to root
return [301, {Location: '/'}, ""]
}
);
and i'v already converted the code in clientside main.js like below
Router.map(function () {
this.route('listFiles', {path: '/'});
this.route('addFile', {path: '/add'});
});
Template.listFiles.helpers({
list: function () {
return Files.find({});
}
});
Template.listFiles.events({
'click #addFileBtn' : function(e) {
e.preventDefault();
Router.go('/add');
}
});
Template.addFile.events({
'click #cancelBtn': function(e){
e.preventDefault();
Router.go('/');
}
});
Meteor.subscribe("files");
the point is that i can't handle how to use http method in serverside code with iron-router
Meteor now directly allows you to attach middleware to the server using the WebApp package, with standard Connect handlers.
Put webapp inside .meteor/packages of your app. You can then attach middleware to WebApp.connectHandlers inside your app. It's not too well documented yet, but treat it as a normal connect server.