I'm trying to migrate users from two instances of API management.
My users log in using an Active directory B2C instance.
When I create the user programmatically, using the REST API, via the Nodejs
SDK, it looks like I'm able to create only users whose provider is "Basic" (but not "AadB2C"):
const newApimUser = await apiClient.user.createOrUpdate(
<resource group>,
<api mgmt>,
ulid(),
{
email: <user email>,
firstName: <first name>,
identities: [
{
id: userAdId,
provider: "aadB2C" // neither "AadB2C" works here
}
],
lastName: <last name>,
state: "active"
}
);
see
https://learn.microsoft.com/en-us/rest/api/apimanagement/user/user_createorupdate
the resulting user has
identities: [
{
id: <user email>,
provider: "Basic"
}
],
which prevents such new users to login using ADb2c.
It looks like this happens because of a bug in the API models:
see https://github.com/Azure/azure-sdk-for-node/issues/3857
Related
I would like to create a public Design Automation Activity and Package so other Forge apps with unknown ClientId & Secret can use our corporate DA tools. So I am setting the isPublic: true flag on the payload but, to my great despair, isn't working.
Take a look at my POST activity payload below:
const activityParams = {
id: DA_ACTIVITY_ID,
commandLine: [
`$(engine.path)\\accoreconsole.exe ` +
`/i \"$(args[inputDwg].path)\" ` +
`/al \"$(appbundles[${DA_APP_BUNDLE_ID}].path)\" ` +
`/s \"$(settings[script].path)\"`
],
parameters: {
inputDwg: {
description: "input .dwg",
localName: "input.dwg",
ondemand: false,
required: true,
verb: "get",
zip: false
},
result: {
description: "result .json",
localName: "result.json",
ondemand: false,
required: false,
verb: "put",
zip: false
}
},
settings: {
script: "(command \"EXTRACTGEOBIMDATA\")\n"
},
description: "GeoBIM Extract Data",
engine: DA_ENGINE,
appbundles: [
fullAppBundleId
],
isPublic: true
}
The first thing I notice is that the response after successful creation of activity doesn't contain the isPublic field:
The second thing I'm forced to notice is that attempting to execute a workitem against that activity result in an error:
Note that when run with the same credentials the activity and workitem are running perfectly fine.
Design Automation V3 let you use individual alias to share an Activity or AppBundle with a specific forge app.
If you look at the documentation when creating an alias for activity and AppBundle, there is an optional parameter you can set in the request body named "receiver". You can specify a forge app client id or nickname if the forge app you want to share with have one setup in Design Automation.
Note that if the Forge app you want to set as receiver use a nickname, you must use that nickname instead of the app client id.
https://forge.autodesk.com/en/docs/design-automation/v3/reference/http/activities-id-aliases-POST/
https://forge.autodesk.com/en/docs/design-automation/v3/reference/http/appbundles-id-aliases-POST/
We don't currently allow people to create public activities. This is because it is not clear how the parties could establish a trust relationship necessary. It sounds like in your scenario the sharing would happen within the same org. Would they have the same email domain (eg. xyz#somecompany.com would share with bla#somecompany.com)?
how do I pass some data between pages in Ionic 4?
Consider this example:
In file1.ts I have:
export class ArchivePage{
constructor() { }
messages = [
{
user: 'user1',
msg: 'Hello!',
type: 0
},
{
user: 'user2',
msg: 'Hi!',
type: 1
}
];
}
Now in file1.html I can simply use *ngFor = "let message of messages" and {{message.user}} {{message.msg}}.
But I have another file2.ts, how can I pass this messages to file2.ts in order to use them in file2.html?
Thanks a lot
You have two options, you can use a shared service for your data as data source and get data from it in the ts files, or you can use Storage for setting your messages in one ts file and retrieve it in the second file, for more details for the second solution, please check the attached documentation link
https://ionicframework.com/docs/angular/storage
I want to integrate Quasar with FeathersJS using Feathers-Vuex
Feathers-Vuex uses a pattern to:
promise to authenticate from localStorage/cookies
.then( /*start the new Vue() app */ )
I created my app with Quasar CLI 1.0.beta16-ish and looked through /src and couldn't find the main entry point for Quasar. I feel like I'm missing something.
What includes src/store/index.js?
quasar.conf.js includes this comment - where is the main.js
// app boot file (/src/boot)
// --> boot files are part of "main.js"
boot: ["axios"],
Feathers-Vuex includes a Nuxt integration guide that may solve the same problem. These packages are all new to me, and I'm excited to learn them!
Thank you!
The part of main.js is included in quasar app.js that you can find in .quasar folder. The src/store/index.js contains the Vuex Store definition. A "store" is basically a container that holds your application state.
For more detail visit - https://quasar-framework.org/guide/app-vuex-store.html https://quasar-framework.org/guide/app-plugins.html
I ended up with two things:
Adding Feathers-Vuex to my backend.
Adding this "boot file" in my Quasar project
The comments are a bread-crumb trail if I ever have to figure it out again :-)
/*
Context:
For 3rd-party API's, we us /src/boot/axios.js
For our own API's, we use FeathersClient (socket.io & REST)
https://docs.feathersjs.com/guides/basics/clients.html
https://docs.feathersjs.com/api/authentication/client.html#appconfigureauthoptions
Our FeathersClient is in `/src/lib/feathersClient.js`
and imported into `/src/store/index.js`
which is imported by Quasar's build system. /src/quasar.conf.js setting(?)
Feathers-vuex integrates Vuex with FeathersClient:
https://feathers-vuex.feathers-plus.com/auth-module.html
Feathers-Vuex proxies it's authentication/logout actions to FeathersClient
https://github.com/feathers-plus/feathers-vuex/blob/master/src/auth-module/actions.js
The parameters for these actions are here:
https://docs.feathersjs.com/api/authentication/client.html#appauthenticateoptions
In addition to this module, you can use FeathersVuex state in UI from here:
https://feathers-vuex.feathers-plus.com/auth-module.html
This module:
Create a Feathers Auth integration for Vue as a Quasar Boot Module.
// Use case: test if user is authenticated
if (Vue.$auth.currentUser()) { ... }
// Use case: get current user's email
name = Vue.$auth.currentUser("email") || "anonymous"
// Use case: Login
Vue.$auth.login({
strategy: 'local',
email: 'my#email.com',
password: 'my-password'
});
// Use case: Logout
// logs out and sends message
let p = Vue.$auth.logout();
// After logout, go home
p.then(() => {
// User data still in browser
router.push({ name: "home"});
// To clear user data, do a hard refresh/redirect - https://feathers-vuex.feathers-plus.com/common-patterns.html#clearing-data-upon-user-logout
location && location.reload(true)
});
*/
export default ({ app, router, store, Vue }) => {
// Create the API demonstrated above
const auth = {
currentUser(prop) {
let u = store.state.auth.user || false;
if (u && prop) return u[prop];
return u;
},
login(authData, quiet) {
return store
.dispatch("auth/authenticate", authData)
.then(() => {
Vue.prototype.$q.notify({
message: "Welcome back!",
type: "info"
});
})
.catch(err => {
if (!quiet) {
console.log(err);
Vue.prototype.$q.notify({
message: "There was a problem logging you in.",
type: "error"
});
}
});
},
logout(quiet) {
return store.dispatch("auth/logout").then(() => {
if (!quiet)
Vue.prototype.$q.notify({
message: "You've been logged out.",
type: "info"
});
});
},
register(authData) {}
};
// Auth from JWT stored in browser before loading the app. true => suppress token not found error
auth.login("jwt", true);
// Add API to Vue
Vue.prototype.$auth = auth;
// If you would like to play with it in the console, uncomment this line:
// console.log(auth);
// Then, in the console:
/*
temp1.login({
strategy: "local",
email: "feathers#example.com",
password: "secret"
})
*/
// If you haven't created this user, see here:
// https://docs.feathersjs.com/guides/chat/authentication.html
// For this REST api endpoint
/*
curl 'http://localhost:3001/users/' -H 'Content-Type: application/json' --data-binary '{ "email": "feathers#example.com", "password": "secret" }'
*/
};
I need to display live interactive graphs based on customer data present in MySQL,for generating the graphs, I am planning to use Amazon Quick Sight but i would like to know whether the generated graphs can be integrated with my web application UI ?
Datasource MYSQL is hosted in AWS.
Any other better design solution is also most welcome :)
I don't think so. Even if you want to share the dashboard to
someone, you need to create a user in QuickSight. Any more than 1
user will be charged by AWS.
The dashboard cannot be public and you need to login to view the
dashboard. If it was public, you could have embedded it in your
webpage as an iframe. But you cannot.
So, I think you are having limited options here, when it comes to
QuickSight.
You can always using D3 or Google Charts to display the data by
exposing REST services for your data in MySQL.
If you have a huge database, you may want to consider indexing the
data to Elasticsearch and perform queries on it.
Check if Kibana + Elasticsearch works out of the box for you.
Good luck!
Update: Dec 28 2018
Amazon announced in Nov 2018, that Amazon QuickSight dashboards can now be embedded in applications. Read more here at this AWS QuickSight Update.
AWS has enabled the embedding of the Dashboards into web apps. The feature was released on 27th Nov 2018. Here are a few helpful links:
1. https://aws.amazon.com/blogs/big-data/embed-interactive-dashboards-in-your-application-with-amazon-quicksight/
2. https://docs.aws.amazon.com/quicksight/latest/user/embedded-dashboards-setup.html
Note: This answer is applicable only if you are using AWS Cognito
In order to generate Quicksight secure dashboard URL, follow the below steps:
Step 1: Create a new Identity Pool. Go to https://console.aws.amazon.com/cognito/home?region=u-east-1 , click ‘Create new Identity Pool’
Give an appropriate name.
Go to the Authentication Providers section, select Cognito.
Give the User Pool ID(your User pool ID) and App Client ID (go to App
Clients in user pool and copy id).
Click ‘Create Pool’. Then click ‘Allow’ to create roles of the
identity pool in IAM.
Step 2: Assign Custom policy to the Identity Pool Role
Create a custom policy with the below JSON.
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "quicksight:RegisterUser",
"Resource": "*",
"Effect": "Allow"
},
{
"Action": "quicksight:GetDashboardEmbedUrl",
"Resource": "*",
"Effect": "Allow"
},
{
"Action": "sts:AssumeRole",
"Resource": "*",
"Effect": "Allow"
}
]
}
Note: if you want to restrict the user to only one dashboard, replace the * with the dashboard ARN name in quicksight:GetDashboardEmbedUrl,
then goto the roles in IAM.
select the IAM role of the Identity pool and assign the custom policy
to the role.
Step 3: Configuration for generating the temporary IAM(STS) user
Login to your application with the user credentials.
For creating temporary IAM user, we use Cognito credentials.
When user logs in, Cognito generates 3 token IDs - IDToken,
AccessToken, RefreshToken. These tokens will be sent to your application server.
For creating a temporary IAM user, we use Cognito Access Token and credentials will look like below.
AWS.config.region = 'us-east-1';
AWS.config.credentials = new AWS.CognitoIdentityCredentials({
IdentityPoolId:"Identity pool ID",
Logins: {
'cognito-idp.us-east-1.amazonaws.com/UserPoolID': AccessToken
}
});
For generating temporary IAM credentials, we call sts.assume role
method with the below parameters.
var params = {
RoleArn: "Cognito Identity role arn",
RoleSessionName: "Session name"
};
sts.assumeRole(params, function (err, data) {
if (err) console.log( err, err.stack); // an error occurred
else {
console.log(data);
})
You can add additional parameters like duration (in seconds) for the
user.
Now, we will get the AccessKeyId, SecretAccessKey and Session
Token of the temporary user.
Step 4: Register the User in Quicksight
With the help of same Cognito credentials used in Step 3, we will
register the user in quicksight by using the quicksight.registerUser
method with the below parameters
var params = {
AwsAccountId: “account id”,
Email: 'email',
IdentityType: 'IAM' ,
Namespace: 'default',
UserRole: ADMIN | AUTHOR | READER | RESTRICTED_AUTHOR | RESTRICTED_READER,
IamArn: 'Cognito Identity role arn',
SessionName: 'session name given in the assume role creation',
};
quicksight.registerUser(params, function (err, data1) {
if (err) console.log("err register user”); // an error occurred
else {
// console.log("Register User1”);
}
});
Now the user will be registered in quicksight.
Step5: Update AWS configuration with New credentials.
Below code shows how to configure the AWS.config() with new
credentials generated Step 3.
AWS.config.update({
accessKeyId: AccessToken,
secretAccessKey: SecretAccessKey ,
sessionToken: SessionToken,
"region": Region
});
Step6: Generate the EmbedURL for Dashboards:
By using the credentials generated in Step 3, we will call the
quicksight.getDashboardEmbedUrl with the below parameters
var params = {
AwsAccountId: "account ID",
DashboardId: "dashboard Id",
IdentityType: "IAM",
ResetDisabled: true,
SessionLifetimeInMinutes: between 15 to 600 minutes,
UndoRedoDisabled: True | False
}
quicksight.getDashboardEmbedUrl(params,
function (err, data) {
if (!err) {
console.log( data);
} else {
console.log(err);
}
}
);
Now, we will get the embed url for the dashboard.
Call the QuickSightEmbedding.embedDashboard from front end with the
help of the above generated url.
The result will be the dashboard embedded in your application with
filter controls.
I know this is a very late reply, but just in case someone else stumbles across this question... We use periscopedata.com to embed BI dashboards in our SaaS app. All that's needed is knowledge of SQL (to create the charts/dashboards) and enough dev knowledge to call their API endpoint to display the dash in your own app.
If we want to prevent multiple logins with same credentials in mobile application how can we do that and we do not have any sessions in mobile so can we do with token based authentication please give me some ideas how to do this.
I am implementing ionic 2 application with back end as node js. I would be very grateful to get suggestions. Thank you in advance.
You can save every login connection and disconnect all previously saved login every time a new connection is created.
If you want to restrict multiple logins on same device and same application then
Two possible solutions:
1.
you can use device uuid Device plugin
Device uuid will be unique. (Don't use device uuid as authentication token)
Install it:
$ ionic plugin add cordova-plugin-device
ans usage
import { Device } from 'ionic-native';
console.log('Device UUID is: ' + Device.uuid);
On login you can use token base authentication.when ever user login save token in localStorage.and when ever app open (index page) check if token is present and still valid than takes user to dashboard otherwise to the login page.
If you don't have any sessions, then it's best to utilize tokens.
There's a great Node.JS API project that already implements tokens on Github, which I've forked and used in the past. You could browse this as an example.
Inside of this project, there's a config for the tokens like so:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
// AccessToken
var AccessToken = new Schema({
userId: {
type: String,
required: true
},
clientId: {
type: String,
required: true
},
token: {
type: String,
unique: true,
required: true
},
created: {
type: Date,
default: Date.now
}
});
module.exports = mongoose.model('AccessToken', AccessToken);
All you would need to do is change the logic to check for the clientId and token for authentication. If the clientId (which is auto-generated each time) is different, then log the user out; forcing them to re-authenticate.
With modern mobile devices, this can easily be done in Javascript with local storage:
var testObject = { 'one': 1, 'two': 2, 'three': 3 };
// Put the object into storage
localStorage.setItem('testObject', JSON.stringify(testObject))…
This allows infinite use on one device, but only ever one device at a time. You could also easily set an expiration on the token as well if you'd like to auto-log out after a period of time.