I'm building a pwa based on REACT that fetches the info from an api based on Laravel 8. In this pwa the first action that the user has to do is logging in.
On my pc it works perfect, it makes the post request and returns the response to continue the process. But, when I try to do it on my Android, when I press the submit input, this doesn't do anything... No validation error, no success...
The function that does the fetch is this:
handleSubmit(event){
let component = this;
let headers = new Headers();
headers.append('Content-Type', 'application/json');
headers.append('Accept', 'application/json');
headers.append('Access-Control-Allow-Origin', '*');
headers.append('Origin','http://192.168.1.132:3000');
fetch('http://127.0.0.1:8000/api/login', {
mode: 'cors',
method: 'post',
headers: headers,
credentials: 'include',
body: JSON.stringify(this.state)
}).then(function(response) {
if (response.status !== 200) {
component.setState({
error: 'Email and/or password are not correct'
});
}else{
component.setState({
error: null
});
return response.json()
}
}).then(function(data) {
component.props.onUserChange(data);
}).catch(error => {
console.log('Something went wrong...');
console.log(component.state.error);
});
event.preventDefault();
}
Do you know the cause of this? Is because the project is in local?
I'll appreciate any idea to solve this.
Thanks in advance!
Related
So yesterday I was developing some sort of offline functionality. Therefore, I added an ApiService that returns Observables.
Currently, I fetch my access_token for jwt-Authentication and then use this token to generate Headers for my API-Request. After a successful request, I save the result to my storage. This works fine. Now here is the problem I want to check for an unsuccessful request (e.g. servers are down, app is offline) and then return my stored result from storage. But I can't get it to work.
Here is my code:
getJobs(): Observable<any> {
this.auth.checkToken()
return from(this.storage.get(ACCESS_TOKEN)).pipe(
switchMap(token => {
let options = this.auth.addToken(token)
return this.http.get(API_URL + "jobs", options)
}),
map(res => {
if (res) {
this.storage.set(JOBS, res)
return res
} else {
return from(this.storage.get(JOBS))
}
}),
catchError(() => {
return from(this.storage.get(JOBS))
})
)
}
Further investigations have shown that after the server or the app is offline neither the map() nor the catchError() functions were executed.
UPDATE:
The solution provided by DJ House is correct. My Code works perfectly in my browser but if I build my app with ionic cordova build android it gets stuck after the this.http.get(...) So it's clearly and issue with cordova
SOLUTION:
Wow! Something magical happened! I've found out that the catchError method gets called BUT after almost 2 Minutes, which is way to slow... So I will implement a timeout.
Thanks
flixoflax
The main issue that you may be facing is you are using the map incorrectly. Map acts upon a normal value (usually, its not an observable) and returns a new value. map() should always return the same type of value. In your map() you are either return the response (which I am assuming is of type Jobs) OR you are return an Observable<Jobs>. This will cause your subscribers to need verbose logic to handle that.
It looks like you are trying to use that map() to set your local storage with the returned jobs from your api. I would recommend using tap() since you aren't trying to change the value you are returning.
function getJobs(): Observable<any> {
this.auth.checkToken()
return from(this.storage.get(ACCESS_TOKEN)).pipe(
switchMap(token => {
let options = this.auth.addToken(token)
return this.http.get(API_URL + "jobs", options)
}),
// change to tap()
tap(res => {
if (res) {
this.storage.set(JOBS, res)
}
}),
catchError(() => {
return from(this.storage.get(JOBS))
})
)
}
If the switchMap throws an error, the tap will be skipped. That will ensure you only set storage if you recieve a value from the API. If you always want to set the storage (even if the API threw an error) then move the tap() to be after the catchError().
Can you please try moving the catchError operator as first operator inside pipe method. This is to ensure that you catch error as soon as you recieve it from observable. Please change it like below:
getJobs(): Observable<any> {
this.auth.checkToken()
return from(this.storage.get(ACCESS_TOKEN)).pipe(
switchMap(token => {
let options = this.auth.addToken(token)
return this.http.get(API_URL + "jobs", options)
}),
catchError(() => {
return from(this.storage.get(JOBS))
})
map(res => {
if (res) {
this.storage.set(JOBS, res)
return res
} else {
return from(this.storage.get(JOBS))
}
}),
)
}
Iam new in ionic with sharepoint
I have developed a Mobile app using ionic3 with sharepoint.
Now i have to get user profile picture in my app.
I have tried these are the way can't achieve here is my tried code.
First way tried like this
Passing Url:-
"https://abc.sharepoint.com/sites/QA/_layouts/15/userphoto.aspx?size=M&accountname=admin#abc.onmicrosoft.com"
Second way tried like this
Passing Url:-
These url iam geting using people picker result. PictureURL property
"https://abc.sharepoint.com/User Photos/Profile Pictures/admin_abc_onmicrosoft_com_MThumb.jpg"
These Second method always return
401 UNAUTHORIZED
Above url using to call this method.
public downloadFile(url: string, fileName: string) {
let options = this._apiHeaderForImageURL();
this._http.get(url, options)
.subscribe((data) => {
//here converting a blob to base 64 For internal view purpose in image src
var reader = new FileReader();
reader.readAsDataURL(data.blob());
reader.onloadend = function () {
console.log("Base64", reader.result);
}
//Here Writing a blob file to storage
this.file.writeFile(this.file.externalRootDirectory, fileName, data.blob(), { replace: true })
.then((success) => {
console.log("File Writed Successfully", success);
}).catch((err) => {
console.log("Error While Wrinting File", err);
});
});
}
public _apiHeaderForImageURL() {
let headers = new Headers({ 'Content-Type': 'image/jpeg' });
headers.append('Authorization', 'Bearer ' + localStorage.getItem("token"));
let options = new RequestOptions({ headers: headers, responseType: 3 });
return options;
}
The first api call worked fine result also sucess but image not displayed properly. Thats the problem iam facing.
The result comes an default image like this only.
pls help me to achieve this. Any help warmly accepted.
Iam doning long time stuff to achieve this still i cant achieve pls give some idea.
Is any other way is available to get user picture in ionic 3 using sharepoint?
I'm trying to implement a user registration system, on android with node as my backend server.
I'm using Node 4.4.5, on localhost, and using the package "email-verification" - https://www.npmjs.com/package/email-verification
So on request from android, a confirmation email with a verification link is sent, which is working fine.
When the link is clicked, a GET request is made, which confirms the user, adds it to the MongoDB database, and a JSON response is sent.
An email is sent to the user that the account is confirmed.
After sending the confirmation email, the server crashes.
Here's my code--
router.get('/email-verification/:URL', function(req, res, next){
var url = req.params.URL;
console.log('email-verify-start');
nev.confirmTempUser(url, function(err, user) {
console.log('error is :' + err);
if (user) {
nev.sendConfirmationEmail(user.email, function(err, info) {
if (err) {
console.log('sending_conf_email_failed');
return res.json({'email': 'sending_conf_email_failed'});
}
console.log('user_confirmed');
res.json({
'email': 'user_confirmed'
});
console.log('Done, and confirmed');
});
} else {
console.log('conf_temp_ser_failed');
return res.json({'email': 'conf_temp_ser_failed'});
}
});
});
And here's my log--
error is :null
user_confirmed
Done, and confirmed
GET /register/email-verification/SfC9VlnUv91RkFBHDURIbHodnYme0RdfbTYBj0I4oXyywrpW 200 5177.724 ms - 26
h:\myapp\coep_updates\node_modules\email-verification\node_modules\nodemailer\node_modules\nodemailer-smtp-transport\src\smtp-transport.js:136
return callback(null, info);
^
TypeError: callback is not a function
at h:\myapp\coep_updates\node_modules\email-verification\node_modules\nodemailer\node_modules\nodemailer-smtp-transport\src\smtp-transport.js:136:20
at h:\myapp\coep_updates\node_modules\email-verification\node_modules\nodemailer\node_modules\nodemailer-smtp-transport\node_modules\smtp-connection\src\smtp-connection.js:279:20
at SMTPConnection._actionStream (h:\myapp\coep_updates\node_modules\email-verification\node_modules\nodemailer\node_modules\nodemailer-smtp-transport\node_modules\smtp-connection\src\smtp-connection.js:966:16)
at SMTPConnection.<anonymous> (h:\myapp\coep_updates\node_modules\email-verification\node_modules\nodemailer\node_modules\nodemailer-smtp-transport\node_modules\smtp-connection\src\smtp-connection.js:594:14)
at SMTPConnection._processResponse (h:\myapp\coep_updates\node_modules\email-verification\node_modules\nodemailer\node_modules\nodemailer-smtp-transport\node_modules\smtp-connection\src\smtp-connection.js:516:16)
at SMTPConnection._onData (h:\myapp\coep_updates\node_modules\email-verification\node_modules\nodemailer\node_modules\nodemailer-smtp-transport\node_modules\smtp-connection\src\smtp-connection.js:353:10)
at emitOne (events.js:77:13)
at TLSSocket.emit (events.js:169:7)
at readableAddChunk (_stream_readable.js:153:18)
at TLSSocket.Readable.push (_stream_readable.js:111:10)
at TLSWrap.onread (net.js:531:20)
Process finished with exit code 1
Till the server crashes, everything's working fine. I receive all emails and responses are sent properly, I even see the JSON response {"email":"user_confirmed"} on my browser. The only problem is that the server crashes afterwards.
EDIT 1
I tried adding return statements-- Still the same problem. I added them here--
return res.json({
'email': 'user_confirmed'
});
I also tried adding a return--
res.json({
'email': 'user_confirmed'
});
return;
No luck till now...
EDIT 2
Ok. so this is actually an open issue on GitHUB, this is reported as a bug.
https://github.com/whitef0x0/node-email-verification/issues/44
So, I tried the GitHUB the solution this way and it is now working flawlessly, even though an official fix is not released...
In the source folder of the module, in the file 'index.js' -->
Go to line 340 --
You'll see this line
callback = options.shouldSendConfirmation;
Change it to -->
callback = function(){};
Hope this helps...
You could change your nev.sendConfirmationEmail method to include the callback as the third argument:
nev.sendConfirmationEmail(user.email, function(err, info) {
if (err) {
console.log('sending_conf_email_failed');
return res.json({'email': 'sending_conf_email_failed'});
}
console.log('user_confirmed');
res.json({
'email': 'user_confirmed'
});
console.log('Done, and confirmed');
}, function(){});
I am trying to login from my Phonegap App using Angularjs (using the Ionic Framework) through Google OAuth2. Currently I am using the http://phonegap-tips.com/articles/google-api-oauth-with-phonegaps-inappbrowser.html for logging in. But it is creating really ugly looking code and quite a hard to understand code when I am using Angular-UI-Router for Ionic.
This issue seems to be spiralling around without any proper answers. I hope it should be solved now. The Google Angular Guys should help.
How to implement Google Auth in phonegap?
The closest topic is How to use Google Login API with Cordova/Phonegap, but this is not a solution for angularjs.
I had to transfer the javascript variable values using the following code:
var el = document.getElementById('test');
var scopeTest = angular.element(el).scope();
scopeTest.$apply(function(){
scopeTest.user = user;
scopeTest.logged_in = true;
scopeTest.name = user.name;
scopeTest.email = user.email;
});
I did the solution like this, where TestCtrl is the Controller where the Login Button resides. There is a mix of jquery based $.ajax calls, which I am going to change to the angualar way. The google_call function basically calls the google_api which is mentioned in the link mentioned above in phonegap-tips.
.controller('TestCtrl', function($scope,$ionicPopup) {
$scope.logged_in = false;
$scope.getMember = function(id) {
console.log(id);
};
$scope.test = function(){
$ionicPopup.alert({"title":"Clicked"});
}
$scope.call_google = function(){
googleapi.authorize({
client_id: 'CLIENT_ID',
client_secret: 'CLIENT_SECRET',
redirect_uri: 'http://localhost',
scope: 'https://www.googleapis.com/auth/plus.login https://www.googleapis.com/auth/userinfo.email'
}).done(function(data) {
accessToken=data.access_token;
// alert(accessToken);
// $loginStatus.html('Access Token: ' + data.access_token);
console.log(data.access_token);
//$ionicPopup.alert({"title":JSON.stringify(data)});
$scope.getDataProfile();
});
};
$scope.getDataProfile = function(){
var term=null;
// alert("getting user data="+accessToken);
$.ajax({
url:'https://www.googleapis.com/oauth2/v1/userinfo?alt=json&access_token='+accessToken,
type:'GET',
data:term,
dataType:'json',
error:function(jqXHR,text_status,strError){
},
success:function(data)
{
var item;
console.log(JSON.stringify(data));
// Save the userprofile data in your localStorage.
window.localStorage.gmailLogin="true";
window.localStorage.gmailID=data.id;
window.localStorage.gmailEmail=data.email;
window.localStorage.gmailFirstName=data.given_name;
window.localStorage.gmailLastName=data.family_name;
window.localStorage.gmailProfilePicture=data.picture;
window.localStorage.gmailGender=data.gender;
window.localStorage.gmailName=data.name;
$scope.email = data.email;
$scope.name = data.name;
}
});
//$scope.disconnectUser(); //This call can be done later.
};
$scope.disconnectUser = function() {
var revokeUrl = 'https://accounts.google.com/o/oauth2/revoke?token='+accessToken;
// Perform an asynchronous GET request.
$.ajax({
type: 'GET',
url: revokeUrl,
async: false,
contentType: "application/json",
dataType: 'jsonp',
success: function(nullResponse) {
// Do something now that user is disconnected
// The response is always undefined.
accessToken=null;
console.log(JSON.stringify(nullResponse));
console.log("-----signed out..!!----"+accessToken);
},
error: function(e) {
// Handle the error
// console.log(e);
// You could point users to manually disconnect if unsuccessful
// https://plus.google.com/apps
}
});
};
})
I am providing this answer for the newbies who faced similar problems like mine while trying to login using Google OAuth2. So asking for Upvotes shamelessly as I am new here too!
Is it possible to communicate an android Application with cakePhp website and share data? If it is possible, I want to create an application that can login into the website; my doubt is:
How to pass user name and password from our application to cakephp websites login page? Can anybody show me an example program?
How cakephp controller handle this request and respond to this request? Please show me an example program?
(I am a beginner in android and cakephp.)
Quick answer -- YES!
We just finished pushing an Android app to the market place that does this exact thing. Here's how we did it:
1) Download and learn to use Cordova PhoneGap (2.2.0 is the latest version) within Eclipse. This makes the whole thing so much easier with just some HTML and a lot of Javascript.
2) In your JS, create methods that push the login information using AJAX parameters. Example:
document.addEventListener('deviceready', onDeviceReady, false);
function onDeviceReady() {
$("#login").click(function() {
$email = $("#UserEmail").val();
$pass = $("#UserPassword").val();
$.ajax({
url : yourURL + 'api/users/login',
async : false,
data : {
'email' : $email,
'password' : $pass
},
dataType : 'json',
type : 'post',
success : function(result) {
/**
* do your login redirects or
* use localStorage to store your data
* on the phone. Keep in mind the limitations of
* per domain localStorage of 5MB
*/
// you are officially "logged in"
window.location.href = "yourUrl.html";
return;
},
error : function(xhr, status, err) {
// do your stuff when the login fails
}
});
}
}
3) In Cake / PHP, your Users controller here will take the username and password data in the AJAX call and use that for its authentication.
<?php
class UsersController extends AppController {
public $name = 'Users';
public function beforeFilter() {
parent::beforeFilter();
$this->Auth->allow('api_login');
}
public function api_login() {
$this->autoRender = false;
if ($this->request->data && isset($this->request->data['email']) && isset($this->request->data['password'])) {
$arrUser = $this->User->find('all',array(
'conditions'=>array(
'email'=> $this->request->data['email'],
'password' => $this->Auth->password($this->request->data['password']),
)
)
);
if (count($arrUser) > 0) {
$this->Session->write('Auth.User',$arrUser[0]['User']);
// Do your login functions
$arrReturn['status'] = 'SUCCESS';
$arrReturn['data'] = array( 'loginSuccess' => 1,'user_id' => $arrUser[0]['User']['id'] );
} else {
$arrReturn['status'] = 'NOTLOGGEDIN';
$arrReturn['data'] = array( 'loginSuccess' => 0 );
}
} else {
$arrReturn['status'] = 'NOTLOGGEDIN';
$arrReturn['data'] = array( 'loginSuccess' => 0 );
}
echo json_encode($arrReturn);
}
}
?>
That's pretty much it. You are now authenticated to CakePHP.
You do not need to use "api_", you can use any function name you want, but this helped us keep a handle on what we allowed mobile users to do versus web users.
Now, these are just the building blocks. You basically have to create a whole version of your site on the phone using HTML and Javascript, so depending on your application it may be easier just to create a responsive design to your site and allow mobile browsing.
HTH!
Use Admad JWT Auth Plugin
If you use cakephp3 change your login function with this one :
public function token() {
$user = $this->Auth->identify();
if (!$user) {
throw new UnauthorizedException('Invalid username (email) or password');
}
$this->set([
'success' => true,
'data' => [
'token' => JWT::encode([
'sub' => $user['id'],
'exp' => time() + 604800
],
Security::salt())
],
'_serialize' => ['success', 'data']
]);
}
You can read this tutorial about REST Api and JWT Auth Implementation
http://www.bravo-kernel.com/2015/04/how-to-add-jwt-authentication-to-a-cakephp-3-rest-api/
if rebuild most of the view pages in cakephp into ajax will seem defeat the purposes of using cakephp as it is.