How can I Connect orientDB to angularJS web application - angularjs

I need to connect orientDB with my angularJS login web application.
after log in user allowed to iput some data to web application and those data also need to be stored in the orient DB data base .
So i need to connect database with my angularJS web application and to use database to store and retrieve data,

This is a sample Angular2 service to connect to OrientDB
import {Injectable} from "#angular/core";
import {Headers, Http} from '#angular/http';
#Injectable()
export class OrientService {
url = "http://localhost:2480/command/yourDbName/"
username = "admin";
password = "admin";
constructor(private http: Http) {
}
command(statement: string, success: (data: any) => void, error: (err: any) => void): void {
var url = this.url + "sql/-/-1"
var headers = new Headers();
headers.append("Authorization", "Basic " + btoa(this.username + ":" + this.password));
this.http.post(url,
JSON.stringify({"command": statement}),
{headers: headers})
.toPromise()
.then(success)
.catch(error);
}
}
Then you can use it as follows:
this.orientService.command(
"SELECT FROM V",
(res) => {
let body = res.json();
...
},
(e) => {
console.log(e)
});
Here you can find a full example: https://github.com/luigidellaquila/geospatial-demo/tree/geeconprague2016
Consider that you will have to enable cross-site requests in OrientDB https://orientdb.com/docs/2.2/Web-Server.html

Related

office-addin-sso with #azure/msal-browser

Is it possible to use office-addin-sso with #azure/msal-browser ?
I would like to:
use OfficeRuntime.auth.getAccessToken() to get the Identity Token.
while at the same time use #azure/msal-browser as the fallback
method.
I have managed to get both the above working and can successfully get the MS Graph access token using just #azure/msal-browser.
Given that we want to use msal-browser/auth code flow with PKCE (and not msal/implicit flow) for the fallback, what would be the most effective way of getting the MS Graph access token in this context.
and given that the office-addin-sso package uses On Behalf Of Flow (requiring a secret and redirect).
Any help/suggestions or guidance would be really appreciated.
I use #azure/msal-browser in the office-addin-sso. My addin is for a single domain and the users are supposed to be logged in on OneDrive so I expect to never need the login via the fallback. I get the token silently from msal and then pass it to MS graph to get an access token. This is the code that does it in the ssoauthhelper.ts:
import * as Msal from '#azure/msal-browser';
export async function getToken_Email() {
try {
const msalConfig: Msal.Configuration = {
auth: {
clientId: "<your client id>", //This is your client ID
authority: "https://login.microsoftonline.com/<tenant id>", //The <tenant> in the URL is the tenant ID of the Azure Active Directory (Azure AD) tenant (a GUID), or its tenant domain.
redirectUri: "https://<your server>/office-js/fallbackauthdialog.html",
navigateToLoginRequestUrl: false,
},
cache: {
cacheLocation: "localStorage", // Needed to avoid "User login is required" error.
storeAuthStateInCookie: true, // Recommended to avoid certain IE/Edge issues.
},
};
const msalInstance = new Msal.PublicClientApplication(msalConfig);
const silentRequest = {
scopes: ["User.Read", "openid", "profile"]
};
let access_token: string;
try {
const loginResponse = await msalInstance.ssoSilent(silentRequest);
access_token = loginResponse.accessToken;
} catch (err) {
if (err instanceof Msal.InteractionRequiredAuthError) {
const loginResponse = await msalInstance.loginPopup(silentRequest).catch(error => {
// handle error
});
} else {
// handle error
}
}
console.log('silent token response: ' + JSON.stringify(access_token));
// makeGraphApiCall makes an AJAX call to the MS Graph endpoint. Errors are caught
// in the .fail callback of that call
const graph_response: any = await makeGraphApiCall(access_token);
console.log('graph response: ' + JSON.stringify(graph_response));
} catch (exception) {
console.log(exception);
}
}
export async function makeGraphApiCall(accessToken: string): Promise < any > {
try {
const response = await $.ajax({
type: "GET",
url: "https://graph.microsoft.com/oidc/userinfo/",
headers: {
access_token: accessToken,
Authorization: 'Bearer ' + accessToken + ' '
},
cache: false,
});
return response;
} catch (err) {
console.log(`Error from Microsoft Graph. \n${err}`);
}
}

Send current logged in user from Django backend to React frontend using axios

I am trying to send current logged in username from django backend to React frontend. I have created an endpoint currentuser/ that works perfectly fine in backend, it returns the expected result but when I call this api endpoint in React using axios,null value is returned there.
Here's the code for backend
#view.py
from django.contrib.auth import get_user_model
from rest_framework import serializers
from rest_framework.response import Response
from rest_framework.views import APIView
User = get_user_model()
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('id', 'username')
class LoggedInUserView(APIView):
def get(self, request):
serializer = UserSerializer(request.user)
return Response(serializer.data)
#urls.py
urlpatterns = [
path('currentuser/', views.LoggedInUserView.as_view(), name='currentuser'),
]
Here's the result when calling the api directly
Here's the code for frontend
class App extends React.Component {
state = {
users: [],
}
getUsers() {
axios.defaults.headers.common['Content-Type'] = 'application/json';
axios.get(`http://localhost:8000/currentuser/`)
.then(res => {
console.log("res :", res);
const user = res.data;
console.log("response from backend", user);
this.setState({ users: user });
console.log(this.state.users);
})
.catch(err => {
console.log("error:", err);
});
console.log(this.state.users);
}
constructor(props) {
super(props);
this.getUsers();
}
render() {
return (.....)
}
};
export default App;
Here's the result when calling the api from the frontend
Any suggestions would be appreciated
Just learning this topic now. Did you login on React front-end? If you just want to retrieve login user's profile.
Here is my solution for your reference.
Firstly, I tried use simple-JWT authentication to set up react and Django.
(google "JWT authentication Django and React", there are many many teaching materials).
Then to log in on react site, and from a response of Django you can retrieve the logged-in user detail. The response.data is a token, which means you can use a "jwt_decode" to get the information you want including: username, id, email. (may have security issue... refer to If you can decode JWT, how are they secure?, just for learning should be fine).
Your code might look like the following:
axios.post("http://127.0.0.1:8000/token/", {
username: username,
password: password,
})
.then((response) => {
let token = response.data.access;
localStorage.setItem("token", token);
let user_id = jwt_decode(response.data.access).user_id;
...
localStorage.setItem("user_id", user_id);
})
Once you got your user_id in localstorage, you can use it to retrieve all the details, your code might look like:
let id = parseInt(localStorage.getItem("user_id"));
const userDetail = (id) => {
const token = localStorage.getItem("token");
axios
.get(`http://127.0.0.1:8000/users/${id}`, {
headers: { Authorization: token },
})
.then(function (response) {
console.log(response.data);
})
.catch(function (error) {
console.log(error);
});
The response.data includes all information you posted on your Django back-end API.
Hope this helped.

'AADSTS500011' error message returned from API call using adalFetch

I have a React application that is registered in Azure Active Directory. In the API Permissions section, I have added permissions to access the API I am trying to access.
I am using the react-adal package to handle login and storage of access tokens when the user enters the app. My understanding is that the access token for the API is created at this point and adalFetch handles the logistics during the call to the API.
The response from the API is an error object (I replaced the actual id's; yes they match exactly and are correct in AAD):
{
message: "AADSTS500011: The resource principal named https://<domain>.onmicrosoft.com/APP_ID/access_as_user was not found in the tenant named TENANT. This can happen if the application has not been installed by the administrator of the tenant or consented to by any user in the tenant. You might have sent your authentication request to the wrong tenant."
msg: "invalid_resource"
}
I have searched high and low to find a solution to why this isn't working. There is documentation on the API, but none specifying a resource or anything beyond the various endpoints i.e. http://thing-api.azurewebsites.net/api/endpointGoesHere
The API page states:
To use the API, apps need to implement modern authentication (OIDC) using AzureAD (AAD) and then request a token from AAD for the API.
The app id in Azure is https://domain.onmicrosoft.com/APP_ID and requires the “access_as_user” scope.
adalConfig.js
import { AuthenticationContext, adalFetch, withAdalLogin } from 'react-adal';
export const adalConfig = {
clientId: CLIENT_ID,
tenant: TENANT,
endpoints: {
thingApi: 'https://<domain>.onmicrosoft.com/APP_ID/access_as_user',
graphApi: 'https://graph.microsoft.com',
},
cacheLocation: 'localStorage',
};
export const authContext = new AuthenticationContext(adalConfig);
export const adalApiFetch = (fetch, url, options) =>
adalFetch(authContext, adalConfig.endpoints.thingApi, fetch, url, options);
export const adalGraphFetch = (fetch, url, options) =>
adalFetch(authContext, adalConfig.endpoints.graphApi, fetch, url, options);
Function for the API call. Executed in componentDidMount.
TrainLanding.jsx
//Returns error
fetchData = () => {
adalApiFetch(fetch, 'http://thing-api.azurewebsites.net/api/EventGet', {})
.then((response) => {
response.json()
.then((responseJson) => {
this.setState({ apiResponse: JSON.stringify(responseJson, null, 2) }, () => {
console.log(this.state.apiResponse)
})
});
})
.catch((error) => {
console.error(error);
})
}
//works perfectly fine
fetchGraph = () => {
adalGraphFetch(fetch, 'https://graph.microsoft.com/v1.0/me', {})
.then((response) => {
response.json()
.then((responseJson) => {
this.setState({ apiResponse: JSON.stringify(responseJson, null, 2) }, () => {
console.log(this.state.apiResponse)
})
});
})
.catch((error) => {
console.error(error);
})
}
I set up a graph API call in the exact same way to test the method, and it works perfectly fine. So I know adal is set up correctly, I just don't understand the error and where I am going wrong. My googling has not yielded any useful results.
Ok, so if you're here, some things to note:
Don't use ADAL. Use MSAL. ADAL is v1 and does not work. Read here for examples: https://www.npmjs.com/package/react-aad-msal
You should wrap your entire app inside the component you get from above. I will show how I did it below.
You must have already registered your app in Azure Active Directory, configured redirect URLs, and included API permissions.
index.js
import { AzureAD, MsalAuthProviderFactory, LoginType } from 'react-aad-msal';
import { msalConfig, authParams } from './msalConfig';
class Index extends Component {
state = {
userInfo: null,
}
userJustLoggedIn = (accInfo) => {
this.setState({
userInfo: accInfo
})
}
render() {
return(
<AzureAD
provider={
new MsalAuthProviderFactory(msalConfig, authParams, LoginType.Redirect)
}
forceLogin={true}
accountInfoCallback={this.userJustLoggedIn}
>
<HashRouter>
<App userInfo={this.state.userInfo}/>
</HashRouter>
</AzureAD>
);
}
}
ReactDOM.render(
<Index/>, document.getElementById('root')
);
This might not be what your index looks like if you are using the most recent version of Create React App. I converted the Index into a component for a couple of reasons. First, the authentication loop for me was getting stuck 1 refresh short when redirecting. Second, so I could store the logged in user's info in state, update with setState (which forces another render), and then pass it as a prop to the rest of my app.
msalConfig.js
export const msalConfig = {
auth: {
authority: process.env.REACT_APP_AUTHORITY, //this should be "https://login.microsoftonline.com/<your-tenant-id>"
clientId: process.env.REACT_APP_CLIENT_ID, //just "<your-client-id>"
redirectUri: process.env.REACT_APP_REDIRECT //"<url of your app or localhost port you dev on>"
},
cache: {
cacheLocation: "localStorage",
storeAuthStateInCookie: true
}
};
export const authParams = {
//can be whatever api scopes you need here **as long as they are from the same API address**
scopes: [
'https://graph.microsoft.com/User.ReadBasic.All',
'https://graph.microsoft.com/email',
'https://graph.microsoft.com/profile',
'https://graph.microsoft.com/User.Read'
],
extraScopesToConsent: [
//any non Microsoft Graph API scopes go here for this example
'any extra strings of APIs to consent to'
]
}
Read above env files and variables here: https://facebook.github.io/create-react-app/docs/adding-custom-environment-variables#what-other-env-files-can-be-used
I have a .env.development and a .env.production with the proper redirect URLs for each.
After you have authenticated the user, you can access the API.
You need to acquire a token silently before each API call and use the token in the request. For me it looks like this:
const authProvider = new MsalAuthProviderFactory(msalConfig, authParams);
console.log(authProvider)
authProvider.getAuthProvider().UserAgentApplication.acquireTokenSilent(authParams)
.then((res) => {
axios({
headers: {
'Authorization': 'Bearer ' + res.accessToken
},
method: 'GET',
url: "api address"
})
.then((response) => {
//do stuff with response
console.log(response)
})
.catch((error) => {
console.log('axios fail: ' + error)
})
})
.catch((error) => {
console.log('token fail: ' + error)
})
I put this into a function and called during componentDidMount.
I will update if anything changes. I hope this helps someone.

How to use Sql server connection in angular 6?

I have do connection in 'Angular6' using sqlserver.
server.js
var express = require('express');
var app = express();
app.get('/', function (req, res) {
var sql = require("mssql");
// config for your database
var config = {
user: 'abc',
password: 'abc',
server: 'servername',
database: 'xyz'
};
// connect to your database
sql.connect(config, function (err) {
if (err) console.log(err);
// create Request object
var request = new sql.Request();
// query to the database and get the records
request.query('select * from tbl', function (err, recordset) {
if (err) console.log(err)
// send records as a response
res.send(recordset);
});
});
});
var server = app.listen(5000, function () {
console.log('Server is running..');
});
data.service.ts
import { Injectable } from '#angular/core';
import { HttpClient } from '#angular/common/http';
#Injectable({
providedIn: 'root'
})
export class DataService {
constructor(private http: HttpClient) { }
getUsers() {
return this.http.get('https://jsonplaceholder.typicode.com/users')
}
getUser(userId) {
return this.http.get('https://jsonplaceholder.typicode.com/users/'+userId)
}
getPosts() {
return this.http.get('https://jsonplaceholder.typicode.com/posts')
}
getPhotos()
{
return this.http.get('https://jsonplaceholder.typicode.com/photos');
}
getTodos()
{
return this.http.get('https://jsonplaceholder.typicode.com/todos');
}
}
Right now I have used dummy API'S for result.
how to get my database results in service?
I have successfully get result from Sqlserver database.
I also want to display record in my Component
user.component.html
<h1>Users</h1>
Can I have to import server.js in user.component.ts.
If yes than how can I do that?
I think you are misunderstanding angular. Angular run into browser and its context is limited to that.
If you need to connect to a database, you need to use some backend technologies, like express and nodejs, as the code you posted.
The main way is to expose some backend services, like REST services, developed with a server side techonology (nodejs, j2ee, php, etc) and then use Angular to ask them for data.
Generally to achieve this goal in angular you should use HttpClient
You should search for a tutorial, like this
Angular example to request data
In angular you should create a service class to call your exposed service, then into that class you could create a method like this:
import {HttpClient, HttpHeaders} from '#angular/common/http';
import {Observable} from 'rxjs';
import {Injectable} from '#angular/core';
import {catchError, map, tap} from 'rxjs/operators';
#Injectable({
providedIn: 'root'
})
export class TestService {
get(): Observable<any> {
return this.http.get([YOUR_BACKEND_SERVICE_URL]).pipe(
catchError(this.handleError(`get`))
);
}
private handleError<T>(operation = 'operation', result?: T) {
return (error: any): Observable<T> => {
console.error(error);
this.log(`${operation} failed: ${error.message}`);
return of(result as T);
};
}
}
Then you should write a component like this:
#Component({
selector: 'app-test',
templateUrl: './test.component.html',
styleUrls: ['./test.component.css']
})
export class TestComponent implements OnInit {
data: any;
constructor(private testService: TestService) { }
ngOnInit() {
this.getData();
}
getData(): void {
this.testService.get().subscribe(data => console.log(data));
}
}
You need to create service and component with AngularCli in order to avoid to manually declare and import them into app.module.ts
For a better understanding of what is happening I suggest you to read Angular Tour of Heroes tutorial, Services section

MEAN 2 Multi Tenant App. Form to create 2 different models

In my quest to learn the MEAN stack i'm building a small multi tenanted app and struggling with getting my users / tenants all signed up. Backend is sorted I believe just cant quite figure out how to get angular to play ball.
Flow... User signs up a new account, Which concurrently creates a new tenant. Like so...
var express = require('express');
var router = express.Router();
var bcrypt = require('bcryptjs');
var Tenant = require('../models/tenant');
var User = require('../models/user');
router.post('/', function (req, res, next) {
var tenant = new Tenant({
name: req.body.name
});
tenant.save(function(err, tenant) {
Tenant.findById(tenant._id, function(err, tenant) {
var user = new User({
first_name: req.body.first_name,
last_name: req.body.last_name,
email: req.body.email,
password: bcrypt.hashSync(req.body.password, 10),
active: req.body.active,
tenant: tenant
})
user.save(function (err, user) {
if (err) {
return res.status(500).json({
title: 'An error has occured',
error: err
});
}
res.status(201).json({
message: 'User created',
obj: user
});
})
});
});
// tenant.findByIdAndUpdate(tenant._id, {owner: user._id});
});
module.exports = router;
This, for the most part, works as intended. At least in testing with postman.
In angular my signup component (in its working state before I tried introducing tenants) looks like:
import { Component, OnInit } from '#angular/core';
import {FormControl, FormGroup, Validators} from "#angular/forms";
import {Router} from "#angular/router";
import {AuthService} from "../auth.service";
import {User} from "../user.model";
import {Tenant} from "../tenant.model";
#Component({
selector: 'app-signup',
templateUrl: './signup.component.html',
styleUrls: ['./signup.component.css']
})
export class SignupComponent implements OnInit{
myForm: FormGroup;
constructor(private router: Router, private authService: AuthService) {}
onSubmit() {
const user = new User(
this.myForm.value.first_name,
this.myForm.value.last_name,
this.myForm.value.email,
this.myForm.value.password
);
this.authService.signup(user)
.subscribe(
data => console.log(data),
error => console.error(error)
);
this.router.navigate(['/signup/success/' + this.myForm.value.email]);
}
ngOnInit() {
this.myForm = new FormGroup({
coName: new FormControl('', Validators.required),
email: new FormControl('', Validators.required),
password: new FormControl('', Validators.required),
active: new FormControl(true, Validators.required)
});
}
}
and my AuthService (again in its working state before i tried introducing tenants) ...
import { Injectable } from "#angular/core";
import { Http, Headers, Response } from "#angular/http";
import 'rxjs/Rx';
import { Observable } from "rxjs";
import { User } from "./user.model";
import { Tenant } from "./tenant.model";
#Injectable()
export class AuthService {
constructor(private http: Http) {}
signup(user: User) {
const body = JSON.stringify(user);
const headers = new Headers({'Content-Type': 'application/json'});
return this.http.post('/api/tenant', body, {headers: headers})
.map((response: Response) => response.json())
.catch((error: Response) => Observable.throw(error.json()));
}
signin(user: User) {
const body = JSON.stringify(user);
const headers = new Headers({'Content-Type': 'application/json'});
return this.http.post('/api/user/signin', body, {headers: headers})
.map((response: Response) => response.json())
.catch((error: Response) => Observable.throw(error.json()));
}
logout() {
localStorage.clear();
}
isLoggedIn() {
return localStorage.getItem('token') !== null;
}
}
Now, i'm not looking for a handout, or anyone to write this for me... just a friendly nudge in the right direction, if that's allowed on here ;) . Would it be easier to just abandon the reactive form and use ngModel? Or perhaps, define a new angular model that is a hybrid of user/tenant?
Cheers.
In case anyone sees this and cares... I was putting a level of importance on my angular models mimicking my mongoose models. I ended up creating a new angular model (signup.model.ts) made up of the relevant fields from both my tenant and user mongoose models. Now I'm not sure this was necessarily the ideal way to structure this, however it works so feel I can put it in as an answer.
Cheers.

Resources