Update event does not work with EWS Access Denied - soap

I am creating Meeting from application using EWS. With soap request
{
"body":{
"m:CreateItem":{
"attributes":[
{
"SendMeetingInvitations":"SendToAllAndSaveCopy"
}
],
"m:Items":[
{
"t:CalendarItem":{
"t:Subject":"Booked from application",
"t:Body":{
"attributes":[
{
"BodyType":"Text"
}
],
"value":"Meeting body"
},
"t:Start":"2016-03-02T13:11:59+00:00",
"t:End":"2016-03-02T13:45:00+00:00",
"t:Location":"room1",
"t:RequiredAttendees":[
{
"t:Attendee":{
"t:Mailbox":{
"t:EmailAddress":"room1#testdomain.onmicrosoft.com"
}
}
}
]
}
}
]
}
},
"headers":{
"Authorization":"Basic somestringsdafsdfsdfsdfsdfsf"
},
"additionalNamespaces":[
"xmlns:m=\"http://schemas.microsoft.com/exchange/services/2006/messages\"",
"xmlns:t=\"http://schemas.microsoft.com/exchange/services/2006/types\""
],
"soapHeader":{
"t:ExchangeImpersonation":{
"t:ConnectingSID":{
"t:PrincipalName":"test007#testdomain.onmicrosoft.com"
}
}
},
"method":"POST",
"url":"https://outlook.office365.com/EWS/Exchange.asmx"
}
I am also trying to edit the meetings duration via application and it works fine also. With SOAP request:
{
"body":{
"m:UpdateItem":{
"attributes":[
{
"SendMeetingInvitationsOrCancellations":"SendToAllAndSaveCopy"
},
{
"MessageDisposition":"SaveOnly"
},
{
"ConflictResolution":"AlwaysOverwrite"
}
],
"m:ItemChanges":{
"t:ItemChange":{
"t:ItemId":{
"attributes":[
{
"Id":"AAApAHJvb20xQGNlcnR1c2ludGVybmF0aW9uYWwub25taWNyb3NvZnQuY29tAEYAAAAAAMWslF/s3JlHvuBz+Grw4nkHAMq37IYLqfhKh5oHo2fodacAAAAAAQ0AAMq37IYLqfhKh5oHo2fodacAAFweeHQAAA=="
},
{
"ChangeKey":"DwAAABYAAADKt+yGC6n4SoeaB6Nn6HWnAABcIvBS"
}
]
},
"t:Updates":{
"t:SetItemField":{
"t:FieldURI":{
"attributes":[
{
"FieldURI":"calendar:End"
}
]
},
"t:CalendarItem":{
"t:End":"2016-03-02T15:00:00+00:00"
}
}
}
}
}
}
},
"headers":{
"Authorization":"Basic somestringssdasasfasfasfasfaf"
},
"additionalNamespaces":[
"xmlns:m=\"http://schemas.microsoft.com/exchange/services/2006/messages\"",
"xmlns:t=\"http://schemas.microsoft.com/exchange/services/2006/types\""
],
"soapHeader":{
"t:ExchangeImpersonation":{
"t:ConnectingSID":{
"t:PrincipalName":"test007#testdomain.onmicrosoft.com"
}
}
},
"method":"POST",
"url":"https://outlook.office365.com/EWS/Exchange.asmx"
}
Where problems starts is, when I create meeting from outlook.office.com using Exchange web interface. I get error with message:
Access is denied. Check credentials and try again., Cannot get ID from
name.
The SOAP request is the same except change keys. I have read on some similar problems that it might be due to the rights on calendar. I am not quite clear with that.
Could you please advise on this problem.
EDIT:
{
"t:ExchangeImpersonation":{
"t:ConnectingSID":{
"t:PrimarySmtpAddress":"test007#testdomain.onmicrosoft.com"
}
}
}

It maybe your impersonation header is test007 the Mailbox your trying to access or just the service account your using ?
I'd suggest you use the PrimarySMTPAddress to ensure you are specifying the Mailbox to access rather then a user eg
"t:ExchangeImpersonation":{
"t:ConnectingSID":{
"t:PrimarySmtpAddress":"test007#testdomain.onmicrosoft.com"
}
Also when you say
Where problems starts is, when I create meeting from outlook.office.com using Exchange web interface. I get error with message
Do you mean you get the error in the Outlook Web App or in your code ?
Cheers
Glen

Related

Strapi email designer plugin reference template to record

I'm currently developing a multi-tenant API with Strapi and for one of the parts I use the Strapi email designer plugin because I want to send some emails but I want them to be custom designed for each tenant, the problem is that the plugin's table is not accessible in the content manager of Strapi so I can only hard code the template to a specific endpoint, is there a way to have the plugin table in the content manager or for it to be referenced to a content manager table something like:
(table)tenant->(field)templateId => (ref-table)plugin-email-designer->(ref-field)templateId
you know so I can switch and set dynamically from the Strapi panel and not with hard-coded endpoints
I've checked your issue briefly, and there is option you are going to like, but it involves using patch-package...
So, let's assume that you have strapi project created and you have added strapi-plugin-email-designer and you are using yarn v1.xx.xx:
yarn add patch-package postinstall-postinstall
Go to node_modules/strapi-plugin-email-designer/server/content-types/email-template/schema.json
change following fileds:
{
...
"pluginOptions": {
"content-manager": {
"visible": true
},
"content-type-builder": {
"visible": true
}
},
...
}
now run
yarn patch-package strapi-plugin-email-designer
now open your projects package.json and add to scripts:
{
"scripts": {
...
"postinstall": "patch-package"
}
}
run
yarn build
yarn develop
head to admin ui, you should see new Collection:
so now you can do that:
Sending Email
Let's assume you added a relation has one called email_template to your model.
Next we need to add custom route, so in /src/api/tenant/routes/ create file called routes.js
/src/api/tenant/routes/routes.js
module.exports = {
routes: [
{
method: 'POST',
path: `/tenants/:id/send`,
handler: `tenant.send`
}
]
}
now, we need to add handler to controller:
/src/api/tenant/controllers/tenant.js
"use strict";
/**
* tenant controller
*/
const { createCoreController } = require("#strapi/strapi").factories;
module.exports = createCoreController("api::tenant.tenant", ({ strapi }) => ({
async send(ctx) {
const { id } = ctx.params;
const { data } = ctx.request.body;
// notice, if you need extra validation you add it here
// if (!data) return ctx.badRequest("no data was provided");
const { to, subject } = data;
const { email_template, ...tenant } = await strapi.db
.query("api::tenant.tenant")
// if you have extra relations it's better to populate them directly here
.findOne({ where: { id }, populate: ["email_template"] });
console.log(email_template);
try {
await strapi
.plugin("email-designer")
.service("email")
.sendTemplatedEmail(
{
to,
//from, < should be set in /config/plugins.js email.settings.defaultFrom
//replayTo < should be set in /config/plugins.js email.settings.defaultReplyTo
},
{
templateReferenceId: email_template.templateReferenceId,
subject,
},
{
...tenant,
// this equals to apply all the data you have in tenant
// this may need to be aligned between your tenant and template
}
);
return { success: `Message sent to ${to}` };
} catch (e) {
strapi.log.debug("📺: ", e);
return ctx.badRequest(null, e);
}
},
}));
don't forget to enable access to /api/tenants/:id/send in admin panel, Settings - Roles
POST http://localhost:1337/api/tenants/1/send
{
"data": {
"to" : "email#example.com",
"subject": "Hello World"
}
}
response:
{
"success": "Message sent to email#example.com"
}
pls note, there is no template validation, e.g. if you give it a wrong template it would not be happy

An error was encountered with the requested page AWS User Pool with Swift

I'm trying to use AWS Cognite User Pool to login with AppleId for iOS application. We couldn't use federated identity, I must use User Pool. While login User Pool, I use hosted UI in iOS application. I had set up service configuration on Aws and iOS application seen below. When I tried to login User Pool, I take a 'An error was encountered with the requested page ' error in WebView.
let hostedUIOptions = HostedUIOptions(identityProvider: "SignInWithApple")
AWSMobileClient.default().showSignIn(navigationController: self.navigationController!, hostedUIOptions: hostedUIOptions) { (userState, error) in
if let error = error as? AWSMobileClientError {
print(error.localizedDescription)
}
if let userState = userState {
print("Status: \(userState.rawValue)")
}
}
AWSConfiguration.json
{
"IdentityManager": {
"Default": {}
},
"CognitoUserPool": {
"Default": {
"PoolId": "eu-west-1_rsPBto6Jx",
"AppClientId": "6atv5t6egacicor9cioXXXXXX",
"AppClientSecret": "171du4k8rf098lmnuvhm2h3o1umqcdfnngcj84tc304moXXXXXXXX",
"Region": "us-east-2"
}
},
"Auth": {
"Default": {
"OAuth": {
"WebDomain": "XXXXX.auth.us-east-2.amazoncognito.com",
"AppClientId": "6atv5t6egacicor9cioXXXXXX",
"AppClientSecret": "171du4k8rf098lmnuvhm2h3o1umqcdfnngcj84tc304moXXXXXXXX",
"SignInRedirectURI": "myapp://",
"SignOutRedirectURI": "myapp://",
"Scopes": ["openid", "email","aws.cognito.signin.user.admin","profile","phone"]
}
}
}
}
How can I solve this problem?
Solution
When I add callback url in consol myapp://sigout, problem was solved.It is my mistake.

Inspect element - how to get parameters sent to a redirected page and simulate it with postman?

In this link there is a quiz when you click on Start Now:
https://www.clinique.com/diagnostics
After the quiz finished, it posts data to a link and immediately redirects to another page with quiz results.
How to find out what data have been posted to the page and is there a way to simulate the final results with the Postman?
Looks like what you're looking for is the Postman Interceptor feature. It allows you to capture and inspect all the requests made from the browser/system you configure it to proxy to.
Then, once your request was captured, and after a bit of filtering (it'll capture every single request made to the server, not only the POST you're interested into) You will be able to replicate it with the Postman client like you'll do with a regular request. e.g. with the quiz you posted:
You'll find the data posted being sent as x-www-form-urlencoded (what a mess!) on a JSON key with the value:
{
"ProfileName":"04-NA-USA ELC Online 4.05.2017",
"QuizVersion":6,
"QuizAnswers":[
{
"attributeName":"welcome",
"attributeRecapValuesLocalized":"mens_concerns",
"recapColumn":1
},
{
"attributeName":"mens_concerns",
"attributeRecapValuesLocalized":"Eye Area",
"recapColumn":0
},
{
"attributeName":"mens_age",
"attributeRecapValuesLocalized":"50 - 59",
"recapColumn":1
},
{
"attributeName":"mens_eye_area_where",
"attributeRecapValuesLocalized":"Lines/Wrinkles",
"recapColumn":0
},
{
"attributeName":"mens_skintype",
"attributeRecapValuesLocalized":"oily-shiny,tight-uncomfortable",
"recapColumn":0
},
{
"attributeName":"mens_sensitivity_frequency",
"attributeRecapValuesLocalized":"Rarely",
"recapColumn":1
},
{
"attributeName":"mens_sensitivity_redness",
"attributeRecapValuesLocalized":"No",
"recapColumn":1
},
{
"attributeName":"recap",
"attributeRecapValuesLocalized":"",
"recapColumn":1
}
],
"SkinType":"2",
"SKUs":[
{
"Eye Area":[
"7YXH-01",
"7ELF-01",
"6TCR-01"
]
},
{
"Daily Care":[
"ZE4L-01",
"ZF7E-01",
"65EM-01",
"Z219-01",
"Z5WW-01"
]
}
],
"UPCs":[
{
"Eye Area":[
"020714632670",
"020714506827",
"020714382742"
]
},
{
"Daily Care":[
"020714734510",
"020714744762",
"020714104726",
"020714649562",
"020714682255"
]
}
],
"Concerns#1":"Eye Area",
"Concerns#2":"Daily Care",
"UsageOrderSKUs":[
"ZE4L-01",
"ZF7E-01",
"65EM-01",
"7YXH-01",
"Z219-01",
"Z5WW-01",
"7ELF-01",
"6TCR-01"
],
"UsageOrderUPCs":[
"020714734510",
"020714744762",
"020714104726",
"020714632670",
"020714649562",
"020714682255",
"020714506827",
"020714382742"
]
}

How to ask permission in Actions on Google without the SDK?

I would like to know the name of the user, however I cannot use the nodejs sdk since I use another language.
How can I ask for permission?
I would prefer a way with the normal json responses.
I hacked this minimal script to get the JSON reponse which the nodejs sdk would return:
gaction.js:
const DialogflowApp = require('actions-on-google').DialogflowApp;
const app = new DialogflowApp({
request: {
body: {
result: {
action: 'Test',
contexts: []
}
},
get: (h) => h
},
response: {
append: (h, v) => console.log(`${h}: ${v}`),
status: (code) => {
return {send: (resp) => console.log(JSON.stringify(resp, null, 2))}
}
}
});
function testCode(app) {
app.askForPermission('To locate you', app.SupportedPermissions.DEVICE_PRECISE_LOCATION);
}
app.handleRequest(new Map().set('Test', testCode));
I'm still no node.js expert so this might be not an optimal solution. When you have installed node and run the command npm install actions-on-google, this will install the necessary dependencies.
When done you just need to run node gaction which will create this output:
Google-Assistant-API-Version: Google-Assistant-API-Version
Content-Type: application/json
{
"speech": "PLACEHOLDER_FOR_PERMISSION",
"contextOut": [
{
"name": "_actions_on_google_",
"lifespan": 100,
"parameters": {}
}
],
"data": {
"google": {
"expect_user_response": true,
"no_input_prompts": [],
"is_ssml": false,
"system_intent": {
"intent": "assistant.intent.action.PERMISSION",
"spec": {
"permission_value_spec": {
"opt_context": "To locate you",
"permissions": [
"DEVICE_PRECISE_LOCATION"
]
}
}
}
}
}
}
If you send now the JSON above you will be asked from Google Home. Have fun!
The request/response JSON formats for the API.AI webhooks with Actions is documented at https://developers.google.com/actions/apiai/webhook
As you've discovered, the data.google.permissions_request attribute contains two fields regarding the request:
opt_context contains a string which is read to give some context about why you're asking for the information.
permissions is an array of strings specifying what information you're requesting. The strings can have the values
NAME
DEVICE_COARSE_LOCATION
DEVICE_PRECISE_LOCATION
If you are using Java or Kotlin there is an Unofficial SDK. It matches the official SDK api nearly exactly.
https://github.com/TicketmasterMobileStudio/actions-on-google-kotlin

Not able to register device with MFP8.0

We are developing ionic app with mfp8.0. We are using the following code to connect with mfp server,
var Messages = {
// Add here your messages for the default language.
// Generate a similar file with a language suffix containing the translated messages.
// key1 : message1,
};
var wlInitOptions = {
// Options to initialize with the WL.Client object.
// For initialization options please refer to IBM MobileFirst Platform Foundation Knowledge Center.
onSuccess:function(){alert('success')},
onFailure:function(){alert('fail')}
};
function wlCommonInit() {
app.init();
}
var app = {
//initialize app
"init": function init() {
app.testServerConnection();
},
//test server connection
"testServerConnection": function testServerConnection() {
WL.App.getServerUrl(function (url) {
});
WLAuthorizationManager.obtainAccessToken()
.then(
function (accessToken) {
alert('accessToken '+JSON.stringify(accessToken));
isPushSupported();
},
function (error) {
alert('Error '+error);
}
);
},
}
function isPushSupported() {
MFPPush.isPushSupported(
function(successResponse) {
alert("Push Supported: " + successResponse);
registerDevice();
}, function(failureResponse) {
alert("Failed to get push support status");
}
);
}
function registerDevice() {
WLAuthorizationManager.obtainAccessToken("push.mobileclient").then(
MFPPush.registerDevice(
{"phoneNumber":""}, // workaround due to a defect in the current release of the product. An empty "phoneNumber" property must be passed at this time.
function(successResponse) {
alert("Successfully registered");
},
function(failureResponse) {
alert("Failed to register");
alert("Failed to register device:" + JSON.stringify(failureResponse));
}
)
);
}
We can able to connect with mfp server. But, We unable register device for push notifcations. We are getting the following error,
"com.ibm.mobilefirstplatform.clientsdk.android.push.api.MFPPushException:Response:Status=404, Text:Error 404: SRVE0295E: Error reported: 404\r\n, Error Message : Not Found"
(or)
"com.ibm.mobilefirstplatform.clientsdk.android.push.api.MFPPushException:Response:Status=500,Text:{\"errorCode\":\"UNEXPECTED_ERROR\",\"errorMsg\":\"Unexpected Error Encountered\"}, Error Message : Unexpected Error Encountered"
Actually, We are getting this error recently. Before that the same code was working fine for us.
Anyone help will be Appreciated!!!
Change the function of Register Device accordingly.
Please go through the link:
https://github.com/MobileFirst-Platform-Developer-Center/PushNotificationsCordova/blob/release80/www/js/index.js
function registerDevice() {
WLAuthorizationManager.obtainAccessToken("push.mobileclient").then(
MFPPush.registerDevice(
null,
function(successResponse) {
alert("Successfully registered");
},
function(failureResponse) {
alert("Failed to register");
alert("Failed to register device:" + JSON.stringify(failureResponse));
}
)
);
}
Your code snippets do not show how did you try to register your application to the push service...
Did you follow the instructions of the push tutorial and looked at the sample push applications before opening a question?
See the tutorials and samples, here: https://mobilefirstplatform.ibmcloud.com/tutorials/en/foundation/8.0/notifications/handling-push-notifications/