Sails hook passport - express

I'm trying to implement Passport strategies into a sails hook, like this I can share on multiple project.
When I try to log I have this error :
Error: passport.initialize() middleware not in use
at IncomingMessage.req.login.req.logIn (/Users/jaumard/IdeaProjects/HookPassportTest/node_modules/sails-hook-passport/node_modules/passport-github/node_modules/passport-oauth/node_modules/passport/lib/passport/http/request.js:30:30)
at /Users/jaumard/IdeaProjects/HookPassportTest/node_modules/sails-hook-passport/api/controllers/AuthController.js:163:11
at Strategy.strategy.success (/Users/jaumard/IdeaProjects/HookPassportTest/node_modules/sails-hook-passport/node_modules/passport/lib/middleware/authenticate.js:194:18)
at verified (/Users/jaumard/IdeaProjects/HookPassportTest/node_modules/sails-hook-passport/node_modules/passport-twitter/node_modules/passport-oauth1/lib/strategy.js:169:16)
at returnResults (/Users/jaumard/IdeaProjects/HookPassportTest/node_modules/sails/node_modules/waterline/lib/waterline/query/finders/basic.js:168:9)
at /Users/jaumard/IdeaProjects/HookPassportTest/node_modules/sails/node_modules/waterline/lib/waterline/query/finders/basic.js:74:16
at /Users/jaumard/IdeaProjects/HookPassportTest/node_modules/sails/node_modules/waterline/lib/waterline/query/finders/operations.js:82:7
at Object.async.each (/Users/jaumard/IdeaProjects/HookPassportTest/node_modules/sails/node_modules/async/lib/async.js:121:20)
at /Users/jaumard/IdeaProjects/HookPassportTest/node_modules/sails/node_modules/waterline/lib/waterline/query/finders/operations.js:425:11
at /Users/jaumard/IdeaProjects/HookPassportTest/node_modules/sails/node_modules/waterline/lib/waterline/query/finders/operations.js:564:5
at Object.async.each (/Users/jaumard/IdeaProjects/HookPassportTest/node_modules/sails/node_modules/async/lib/async.js:121:20)
at _buildChildOpts (/Users/jaumard/IdeaProjects/HookPassportTest/node_modules/sails/node_modules/waterline/lib/waterline/query/finders/operations.js:453:9)
at _execChildOpts (/Users/jaumard/IdeaProjects/HookPassportTest/node_modules/sails/node_modules/waterline/lib/waterline/query/finders/operations.js:421:8)
at /Users/jaumard/IdeaProjects/HookPassportTest/node_modules/sails/node_modules/waterline/lib/waterline/query/finders/operations.js:80:10
at bound (/Users/jaumard/IdeaProjects/HookPassportTest/node_modules/sails/node_modules/lodash/dist/lodash.js:957:21)
at applyInOriginalCtx (/Users/jaumard/IdeaProjects/HookPassportTest/node_modules/sails/node_modules/waterline/lib/waterline/utils/normalize.js:421:80)
I read that I have to add some middleware in config/http.js
middleware: {
passportInit : require('passport').initialize(),
passportSession : require('passport').session(),
order: [
'startRequestTimer',
'cookieParser',
'session',
'passportInit',
'passportSession',
'myRequestLogger',
'bodyParser',
'handleBodyParserError',
'compress',
'methodOverride',
'poweredBy',
'router',
'www',
'favicon',
'404',
'500'
]
}
All it's working after this but I'm under an installable hook and don't want to manually change http.js, is there a way to modify this from the hook ? Or fix the error without adding this.

If I understand correctly, you need to init passport.js in your middleware but want to avoid having to manually edit http.js in each of your projects. To do that you'd create an installable hook like so:
module.exports = function passware(sails) {
sails.config.http.middleware = {
passportInit : require('passport').initialize(),
passportSession : require('passport').session(),
order: [
'startRequestTimer',
'cookieParser',
'session',
'passportInit',
'passportSession',
'myRequestLogger',
'bodyParser',
'handleBodyParserError',
'compress',
'methodOverride',
'poweredBy',
'router',
'www',
'favicon',
'404',
'500'
]
}
return {};
}
To use it you simply copy the hook into your node_modules or npm publish and npm install it in your projects.

Related

CASL Vue - How to access $can in route guard

I am building a Nuxt app and trying to create a route guard. How can I access $can in my Nuxt middleware?
export default (context) => {
const { route } = context
route.matched.some((routeRecord) => {
const options = routeRecord.components.default.options
console.log(options)
// should use $can here
return true
})
}
I import the following in my nuxt.config.js:
plugins: [
{ src: '#plugins/vue-can.js' },
]
I add casl as plugins on the Nuxt $auth module:
auth: {
plugins: [
'#plugins/vue-casl.js',
]
}
This is because I need to access $auth.user in my plugins.
All of this works good, except I can't find $abilities or $can in my Nuxt middleware.
PS: I am talking about this package: #casl/vue
$abilities and $can should both be available as properties of the context object in your middleware, so you should be able to access them using context.$foo.
If you don't see it, it is probably because it was not injected properly. The plugin you registered in your nuxt.config.js should use inject to add $can to the global vue instance and make it available as a property of this and context. See the documentation for further detail: https://nuxtjs.org/docs/2.x/directory-structure/plugins/#inject-in-root--context

How to add service worker to Vue.js project?

I'm trying to use a service worker in my Vue.js project. I have it functioning with a very basic worker that I just dropped into my public/ directory (example below), but this doesn't allow me to load dependencies using require(), which is what I'd like to do next.
self.addEventListener('install', event => {
self.skipWaiting();
console.log(self)
});
self.addEventListener('fetch', function(event) {
const url = new URL(event.request.url);
console.log(url)
})
I found service-worker-loader, but it presents me with this during compilation: Syntax Error: TypeError: Cannot read property 'unlink' of null. The error persists even when I provide a serviceWorker.js file that is completely blank. My vue.config.js has the loader configured:
module.exports = {
configureWebpack: {
module: {
rules: [
{ test: /serviceWorker\.js$/, use: { loader: "service-worker-loader" }}
]
}
}
}
And I'm referencing my worker using import registerServiceWorker from 'service-worker-loader!./serviceWorker';.
Am I missing something basic? What's the "standard" way to include custom service worker code into a Vue.js project?

Nuxt static generated page and axios post

I have a Nuxt project. Everything is OK when I generate a static page.
However, I need to send a POST request to the other server.
I tried to use both a proxy in nuxt.config.js and just direct query, but after deploy to the ngnix eventually, nothing works.
Please help.
UPDATE. Steps to reproduce.
Create Nuxt App including axios and proxy
Configure your proxy for other webservice:
proxy: {
'/api': {
target: 'http://example.com:9000',
pathRewrite: {
'^/api': '/',
},
},
changeOrigin: true,
},
call this service somewhere in the code:
const result = await this.$axios.post('/api/email/subscribe', {email: email})
run "yarn dev" and test the service. It works locally properly.
run 'nuxt generate' and deploy the static code hosting service, for example, hosting.com
run your page which calls the above-mentioned service.
As a result, instead of making POST call to the hosting.com/api/email/subscribe, it calls localhost:3000/api/email/subscribe.
Be sure to install the nuxt versions of axios and proxy in your project #nuxt/axios and #nuxtjs/proxy
after that in your nuxt.config.js add axios as module plus this options for axios and proxy:
modules: [
// Doc: https://axios.nuxtjs.org/usage
'#nuxtjs/axios',
//more modules if you need
],
/*
** Axios module configuration
*/
axios: {
proxy: true,
// See https://github.com/nuxt-community/axios-module#options
},
proxy: {
'/api/': {
target: process.env.AXIOS_SERVER, // I use .env files for the variables
pathRewrite: { '^/api/': '' }, //this should be your bug
},
},
now you can use axios in any part of the code like this
const result = await this.$axios.post('/api/email/subscribe', {email: email})
it will internally resolve to AXIOS_SERVER/email/subscribe without cause cors issues.
EXTRA: test enviroments in local using multiples .env files
you can configure .env for dev and .env.prod for production, after that in local you can use yarn build && yarn start for test your app with your production enviroment. You only need add this at the top of your nuxt.config.js file
const fs = require('fs')
const path = require('path')
if (process.env.NODE_ENV === 'production' && fs.existsSync('.env.prod')) {
require('dotenv').config({ path: path.join(__dirname, `.env.prod`) })
} else {
require('dotenv').config()
}
By definition on the Nuxt docs page what nuxt generate does is: Build the application and generate every route as a HTML file (used for static hosting).
Therefore, using proxy is out of question here. Take note that you path is not even being rewritten.
And probably the result you're looking for is not hosting.com/api/email/subscribe (wit /api), but hosting.com/email/subscribe.
Nevertheless, if you use nginx then I don't think you should use Nuxt's proxy option. Nginx is built just for that so point your API calls there and in nginx config file just declare where it should point further.

AngularFireAuthGuard with multiple conditions

I am working on a Ionic project which is using AngularFire. Application has two main features.
Feature 1. Requires users to create an account and login.
Feature 2. Doesn't require an account or logging in.
I am using AngularFireAuthGuard with "redirectUnauthorizedToLogin" pipe to control routing.
const redirectUnauthorizedToLogin = () => redirectUnauthorizedTo(['login']);
{ path: '...', loadChildren: '...', canActivate: [AngularFireAuthGuard], data: { authGuardPipe: redirectUnauthorizedToLogin } },
Both features interact with FireStore. Due to security reasons, I want to implement Firebase Anonymous Sign-in. So, for the feature 2, I can control who can write to db without allowing permission to everyone. Meanwhile feature 1 will still require an account.
Here comes the problem because I couldn't find a way to add two conditions to the feature 1 guard something like
if (is anonymous || not logged in) redirectToLogin
As far as I can see, redirectUnauthorizedToLogin counts anonymous sign-in as authorized.
I checked the official documents and I see that there is an "IsNotAnonymous" built-in pipe but it is only referred once and I couldn't find any other usage of it.
I hope someone can help me about this.
Thanks in advance,
Ionic:
Ionic CLI : 5.2.1
Ionic Framework : #ionic/angular 4.6.0
#angular-devkit/build-angular : 0.13.9
#angular-devkit/schematics : 7.2.4
#angular/cli : 7.3.9
#ionic/angular-toolkit : 1.4.0
"#angular/fire": "^5.2.1",
"firebase": "^5.11.1",
Cordova:
Cordova CLI : 8.1.2 (cordova-lib#8.1.1)
Cordova Platforms : android 7.1.4
Utility:
cordova-res : 0.6.0
native-run : 0.2.7
System:
Android SDK Tools : 26.1.1 (D:\Sdk)
NodeJS : v11.4.0 (D:\nodejs\node.exe)
npm : 6.4.1
OS : Windows 10
If you checkout the source code, you can see how they implemented isNotAnonymous here: https://github.com/angular/angularfire/blob/5.2.3/src/auth-guard/auth-guard.ts#L32 but the problem is that isNotAnonymous rejects but does not redirect. I think you can basically emulate this line: https://github.com/angular/angularfire/blob/5.2.3/src/auth-guard/auth-guard.ts#L37 to add the redirect.
These are pipe-able, so you should be good to go with:
import { AngularFireAuthGuard, isNotAnonymous } from '#angular/fire/auth-guard';
export const redirectAnonymousTo = (redirect: any[]) =>
pipe(isNotAnonymous, map(loggedIn => loggedIn || redirect)
);
const redirectUnauthorizedToLogin = () => redirectAnonymousTo(['login']);
export const routes: Routes = [
{ path: '', component: AppComponent },
{
path: 'items',
component: ItemListComponent,
canActivate: [AngularFireAuthGuard],
data: { authGuardPipe: redirectUnauthorizedToLogin }
}
];
If unauthenticated or anonymous, it will return false, so the redirect will happen, otherwise it will resolve to true.
I have not tried executing this code, but hopefully it will be a good start.

How to implement background sync with nuxtjs/pwa?

I am trying to use workbox background-sync in Nuxtjs via #nuxt/pwa-module.
this is my workbox property in nuxt.config.js file:
workbox: {
importScripts : [
'sw-background-sync.js'
]
}
contents of plugins/sw-background-sync.js file :
console.log("backsync called")
workbox.routing.registerRoute(
'https:\/\/example.com\/api\/Survey\/post.*',
new workbox.strategies.NetworkOnly({
plugins: [
new workbox.backgroundSync.Plugin('myQueueName', {
maxRetentionTime: 24 * 60
})
]
}),
'POST'
);
Offline caching is supposed to work by default and it is working fine. but when I uncomment importScripts and refresh the page I get this error in console :
backsync called
workbox-sw.js:1 Uncaught Error: Config must be set before accessing workbox.* modules
at Proxy.setConfig (workbox-sw.js:1)
at sw.js:8
Any example of how to implement pwa background sync with nuxtjs would be appreciated.
Thank you very much.
Actually I should put the script inside workboxExtensions property in nuxt.config.js file:
workbox: {
workboxExtensions : '#/plugins/sw-background-sync.js'
}
When using workbox you can also put:
strategyPlugins:[{
use:'BackgroundSync',
config: {}
}],
I am still trying to find out what config to put in there.