Ember CLI + Ember Data + Simple Auth: authorize gets not called - javascript

i am using Ember CLI + Ember Data + Simple Auth. The authenticator is working fine. But when im am doing a Rest Call with Ember Data Rest Adapter this.store.findAll("user"); the authorize function in my custom authorizer don't gets called.
The Rest API Endpoint is on an other domain, so i added the url to the crossOriginWhitelist in my environment.js.
environment.js:
module.exports = function(environment) {
var ENV = {
// some configuration
};
ENV['simple-auth'] = {
crossOriginWhitelist: ['http://api.xxxx.com'],
authorizer: 'authorizer:xxxx',
routeAfterAuthentication: 'dashboard',
};
return ENV;
};
authorizer
import Ember from 'ember';
import Base from 'simple-auth/authorizers/base';
var XXXXAuthorizer = Base.extend({
authorize: function(jqXHR, requestOptions) {
// Some Code, gets not called, damn it :(
}
});
export default {
name: 'authorization',
before: 'simple-auth',
initialize: function(container) {
container.register('authorizer:xxxx', XXXXAuthorizer);
}
};
index.html
....
<script>
window.XXXXWebclientENV = {{ENV}};
window.ENV = window.MyAppENV;
window.EmberENV = window.XXXXWebclientENV.EmberENV;
</script>
<script>
window.XXXXWebclient = require('xxxx-webclient/app')['default'].create(XXXXWebclientENV.APP);
</script>
....
Thanks for help :)

I had a similar problem. For me it was the crossOriginWhitelist config.
I set it like this:
// config/environment.js
ENV['simple-auth'] = {
crossOriginWhitelist: ['*'] // <-- Make sure it's an array, not a string
};
to see if I could get it working (I could), then I could narrow it down to figure out exactly what URL I should use to enforce the restriction (port number and hostname etc).
Don't leave it like that though!
You should actually figure out what URL works for the whitelist, and use that.

I am facing the same issue. I have same setup but the authorize function is not being called. May be you can try by adding the port number in your crossOriginWhiteList url.
I am adding window.ENV = window.MyAppENV line in new initializer which runs before simple-auth. You have added that in index file and may be that is the reason why simple-auth is not able to read your configuration.
Does the other configuration routeAfterAuthentication: 'dashboard', works properly? If not then this might be the reason. Try adding new initializer like
export default {
name: 'simple-auth-config',
before: 'simple-auth',
initialize: function() {
window.ENV = window.MyAppNameENV;
}
};

Related

How to create custom Registration and Login API using Strapi?

I am using strapi to create APIs.
I want to implement my own Registration API and Login API.
I checked the documentation of strapi but i am not finding any custom API for this.
can any one help me on this?
Same answer, but in more detail:
Strapi creates an Auth controller automatically for you and you can overwrite its behavior.
Copy the function(s) you need (e.g. register) from this file:
node_modules/strapi-plugin-users-permissions/controllers/Auth.js
to:
your_project_root/extensions/users-permissions/controllers/Auth.js
Now you can overwrite the behavior, e.g. pass a custom field inside the registration process {"myCustomField": "hello world"} and log it to the console:
async register(ctx) {
...
...
// log the custom field
console.log(params.myCustomField)
// do something with it, e.g. check whether the value already exists
// in another content type
const itExists = await strapi.query('some-content-type').findOne({
fieldName: params.myCustomField
});
if (!itExists) {
return ctx.badRequest(...)
} else {
console.log('check success')
}
}
Actually, strapi creates an Auth controller to handle these requests. You can just change them to fit in your need.
The path to the controller is:
plugins/users-permissions/controllers/Auth.js
in order to create custom users-permissons apis on server side you have to create
src/extensions/users-permissions/strapi-server.js
and in that file can write or override existing user-permissions plugin apis
here is the example for users/me
const _ = require('lodash');
module.exports = (plugin) => {
const getController = name => {
return strapi.plugins['users-permissions'].controller(name);
};
// Create the new controller
plugin.controllers.user.me = async (ctx) => {
const user = ctx.state.user;
// User has to be logged in to update themselves
if (!user) {
return ctx.unauthorized();
}
console.log('calling about meeeeeeeeeee------')
return;
};
// Add the custom route
plugin.routes['content-api'].routes.unshift({
method: 'GET',
path: '/users/me',
handler: 'user.me',
config: {
prefix: '',
}
});
return plugin;
};

Value not set to global variable in JS/AngularJs

I am using gulp to run and build to run my application. I am getting file contents using $http service in my index.js file and then setting value of a variable like
window.variablex = "http://localhost:8080/appname".
here is how I am doing it (in index.js)
(function ()
{
'use strict';
angular
.module('main')
.controller('IndexController', IndexController);
function IndexController($http){
$http.get('conf/conf.json').success(function(data){
window.variable = data.urlValue;
}).error(function(error){
console.log(error);
});
}
});
And I've created a factory to call the rest APIs of my backend application like
(function(){
'use strict';
angular
.module('main')
.factory('testService',['$resource',testService]);
function agentService($resource){
var agents = $resource('../controller/',{id:'#id'},
{
getList:{
method:'GET',
url:window.variable+"/controller/index/",
isArray:false
}
});
Now, I except a rest call to made like
http://localhost:8080/appname/controller
But it always sends a call like http://undefined/appname/controller which is not correct.
I can get the new set value anywhere else, but this value is not being set in resource service objects somehow.
I am definitely missing something.
Any help would be much appreciated
As you are using Gulp, I advise you to use gulp-ng-config
For example, you have your config.json:
{
"local": {
"EnvironmentConfig": {
"api": "http://localhost/"
}
},
"production": {
"EnvironmentConfig": {
"api": "https://api.production.com/"
}
}
}
Then, the usage in gulpfile is:
gulp.task('config', function () {
gulp.src('config.json')
.pipe(gulpNgConfig('main.config', {
environment: 'production'
}))
.pipe(gulp.dest('.'))
});
You will have this output:
angular.module('myApp.config', [])
.constant('EnvironmentConfig', {"api": "https://api.production.com/"});
And then, you have to add that module in your app.js
angular.module('main', [ 'main.config' ]);
To use that variable you have to inject in your provider:
angular
.module('main')
.factory('testService', ['$resource', 'EnvironmentConfig', testService]);
function agentService($resource, EnvironmentConfig) {
var agents = $resource('../controller/', {id: '#id'},
{
getList: {
method: 'GET',
url: EnvironmentConfig + "/controller/index/",
isArray: false
}
});
}
#Kenji Mukai's answer did work but I may have to change configuration at run time and there it fails. This is how I achieved it (in case anyone having an issue setting variables before application gets boostrap)
These are the sets that I followed
Remove ng-app="appName" from your html file as this is what causing problem. Angular hits this tag and bootstraps your application before anything else. hence application is bootstratped before loading data from server-side (in my case)
Added the following in my main module
var injector = angular.injector(["ng"]);
var http = injector.get("$http");
return http.get("conf/conf.json").then(function(response){
window.appBaseUrl = response.data.gatewayUrl
}).then(function bootstrapApplication() {
angular.element(document).ready(function() {
angular.bootstrap(document, ["yourModuleName"]);
});
});
This will load/set new values everytime you refresh your page. You can change conf.json file even at runtime and refreshing the page will take care of updating the values.

Ember.js project - TypeError: session is undefined

I'm trying to run an Ember project that I had to upgrade it's packages, but now I run into deprecation issues.
My current issue is that when I press 'login' I see a TypeError: session is undefined message when I open the developer console in firefox.
I have no knowledge of Ember really, so to my very limited understanding is that there's a build javascript file that's based off an MCR architecture of little javascript files.
So here's the part of the big one:
define('genesis/controllers/login', ['exports', 'ember'], function (exports, _ember) {
exports['default'] = _ember['default'].Controller.extend({
loginMessage: "",
actions: {
authenticate: function authenticate() {
var credentials = this.getProperties('identification', 'password'),
authenticator = 'simple-auth-authenticator:jwt';
this.set("loginMessage", "");
var session = this.get('session');
session.authenticate(authenticator, credentials);
}
}
});
});
And this is the small one it's based off:
templates/login.js
import Ember from 'ember';
export default Ember.Controller.extend({
loginMessage: "",
actions: {
authenticate: function() {
var credentials = this.getProperties('identification', 'password'),
authenticator = 'simple-auth-authenticator:jwt';
this.set("loginMessage", "");
var session = this.get('session');
session.authenticate(authenticator, credentials);
}
}
});
I had to change Ember.ObjectController.extend to Ember.Controller.extend due to deprecation.
Assuming session is a service, you need to inject it into the controller in order to be able to use it. Without injecting, this.get('session') would return undefined.
Check this documentation on more details about dependency injection.
Turned out that during the upgrade I had removed one package from package.json named
ember-simple-auth-token, but I'll give credit to Charizard for letting me find it due to his answer.
I also had to make some tiny changes to the template file.
templates/login.js:
import Ember from 'ember';
export default Ember.Controller.extend({
session: Ember.inject.service(),
loginMessage: "",
actions: {
authenticate: function() {
var credentials = this.getProperties('identification', 'password'),
authenticator = 'authenticator:jwt';
this.set("loginMessage", "");
this.get('session').authenticate(authenticator, credentials);
}
}
});

Using Ember initializers to set domain related data

I have a single Ember app that needs to use different data depending on the domain that it's running on. For example, on domain1.com the site title might be "Domain 1 Website", whereas for domain2.org the site title could be "Cool Site!"
I need to be able to use the data in routes, controllers and templates.
My initializer so far:
import { request } from 'ic-ajax';
export function initialize(container, application) {
var domain = document.location.host;
return request('http://api/sites?domain=' + domain, {} ).then(function(response) {
// make the response available to routes, controllers and templates
});
}
export default {
name: 'site-data',
initialize: initialize
};
If you take a look at the docs:
http://guides.emberjs.com/v1.10.0/understanding-ember/dependency-injection-and-service-lookup/#toc_dependency-injection-with-code-register-inject-code
The second example
Ember.Application.initializer({
name: 'logger',
initialize: function(container, application) {
var logger = {
log: function(m) {
console.log(m);
}
};
application.register('logger:main', logger, { instantiate: false });
application.inject('route', 'logger', 'logger:main');
}
});
and the following explanation shows you how you can use .inject to make one of your variables, services or functions available to whatever objects you need within your application.

How should I store current user details in EmberJS?

I have an EmberJS application generated using ember-cli. I'm currently using simple-auth with a custom authenticator.
In the authenticator, when the user logs in I want to save his details so that I can use it later.
I have the following code:
authenticate: function(options) {
var self = this;
return new Ember.RSVP.Promise(function(resolve, reject){
API.user.login(options.username, options.password, true).done(function(data) {
// #TODO: Save current user
resolve(data.id);
}).fail(function() {
reject();
});
});
},
User data is available in the variable data.user.
I tried using Ember.set('App.currentUser', data.user); but it's not working. What should I do?
I think it works easiest to use an initializer. Theres several ways you can resolve the user, I think it is easiest if you pass the user_email alongside the grant token from the API
//initializers/session-user.js
import Ember from "ember";
import Session from "simple-auth/session";
export function initialize(container) {
Session.reopen({
setCurrentUser: function() {
var accessToken = this.get('access_token');
var self = this;
if (!Ember.isEmpty(accessToken)) {
return container.lookup('store:main').find('user', {
email: self.get('user_email')
}).then(function (users){
self.set('currentUser', users.get('firstObject'));
});
}
}.observes('access_token')
});
}
export default {
name: 'session-user',
before: 'simple-auth',
initialize: initialize
};
Check this thread for where the idea of this came from: http://discuss.emberjs.com/t/best-practice-for-loading-and-persisting-current-user-in-an-authenticated-system/6987
And if you are using simple-auth > 0.8.0-beta.1 you will need to adjust the initializer
I ended up creating a custom Sessions controller and setting the current user object there, and then creating an alias from the application controller.
Something like what's in this article.

Categories

Resources