whmcs phone verify hook - hook

I write a costume phone verification module for WHMCS
and i used the following hook to redirect clients to verification module before they check out their order.
add_hook('ShoppingCartValidateCheckout', 1, "PV");
function PV($vars) {
$clientID = intval($_SESSION['uid']);
$isVerified = //check from database
if ($isVerified != 'true') {
return 'send code';
}
this hook works fine when client is logged in but for new clients that register in page cart.php?a=view this hook not work because $_SESSION['uid'] returns 0 . which hook should i use for the above exception?

my problem solved by using the following hook
add_hook('ClientLogin', 1, function($vars) {
// Perform hook code here...
});

Related

XERO-NODE SDK => How to choose a specific email template

I am using the Xero-node SDK to automatically create client invoices which works well.
At the end of the process, I would like to automatically email the client the invoice.
In the documentation it has the following example:
const xeroTenantId = 'YOUR_XERO_TENANT_ID';
const invoiceID = '00000000-0000-0000-0000-000000000000';
const requestEmpty: RequestEmpty = { };
try {
const response = await xero.accountingApi.emailInvoice(xeroTenantId, invoiceID, requestEmpty);
console.log(response.body || response.response.statusCode)
} catch (err) {
const error = JSON.stringify(err.response.body, null, 2)
console.log(`Status Code: ${err.response.statusCode} => ${error}`);
}
I have 2 questions:
The requestEmpty method does not work in javascript. Does anyone know the correct structure of requestEmpty?
I have used requestEmpty = { } but this throws an error => even though the system does actually send an email (probably a bug)
AND....
Is there a way for me to specify the email template that I would like the invoice to use (if I have specific templates setup in the web version)? Currently it seems to use the default Xero email template.
If you don't get an answer to your first query here, please can you raise it on the SDK page in Github and the Xero SDK team will look into this for you.
With regards to point 2, it is not possible to choose the email template when sending through the API, a basic template is used.

Registering call logging service into RingCentral Embeddable results in undefined error

It appears all my current attempts to register a third party service (My Single Page Application) using RingCentral Embeddable are proving difficult. I'm using the postMessage API with type rc-adapter-register-third-party-service and the result remains "undefined"
document.querySelector("#rc-widget-adapter-frame").contentWindow.postMessage({
type: 'rc-adapter-register-third-party-service',
service: {
name: 'TestService'
}
}, '*');
Is there a resolution to this as I'm successful receiving inbound calls. When I use type "rc-adapter-new-call" for outbound calls it also works but third party integration is proving difficult and the link neither pops up on the softPhone.
For more details see...
https://github.com/ringcentral/ringcentral-embeddable/blob/master/docs/third-party-service-in-widget.md#register-your-service
Thanks!
I think the issue is that we need to register service after widget loaded.
Here is a demo for it. Let me update the embeddable docs.
var registered = false;
window.addEventListener('message', function (e) {
const data = e.data;
if (data && data.type === 'rc-login-status-notify' && registered === false) {
registered = true;
registerService();
}
});

Using 2FA for password reset

My application uses Asp.Net Identity and sends a Two Factor code to my Auth app on login. This is pretty standard (as there lots of examples on the net) and uses the SendCode() method. My understanding is that the 'magic' is done by this line:
// Generate the token and send it
if (!await SignInManager.SendTwoFactorCodeAsync(model.SelectedProvider))
{
View("Error");
}
My requirement is to ensure the user goes through the same process of 2FA when they want to change their password after they have logged in.
My issue is that when the code to send the 2FA code is executed:
if (!await SignInManager.SendTwoFactorCodeAsync(model.SelectedProvider))
{
View("Error");
}
I receive the error 'UserID not found':
Server Error in '/MSPortal' Application.
UserId not found.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.InvalidOperationException: UserId not found.
Source Error:
Line 555:
Line 556: // Generate the token and send it
Line 557: if (!await SignInManager.SendTwoFactorCodeAsync(model.SelectedProvider))
Line 558: {
Line 559: return View("Error");
I know SendTwoFactorCodeAsync() calls GetVerifiedUserIdAsync() but my understanding is that the user is verified now that I have already logged in using 2FA.
Does anyone know why I would be getting this error?
Thanks.
I've worked around this by overriding SendTwoFactorCodeAsync() in IdentityConfig.cs. In this override, I first call GetVerifiedUserIdAsync() as per usual but then if that is 0 I get the User's ID from the Current HttpContext.
I am not stating this is the best way but it's what I have done thus far and its got me moving ahead in my aim of having 2FA for login, change password and forgot password.
The code (likely to go through some refactoring if I get feedback) is:
public override async Task<bool> SendTwoFactorCodeAsync(string provider)
{
int userId = 0;
try
{
userId = await GetVerifiedUserIdAsync();
if (userId == 0)
{
userId = Convert.ToInt32(HttpContext.Current.User.Identity.GetUserId());
}
if (userId == 0)
return false;
}
catch
{
return false;
}
var token = await UserManager.GenerateTwoFactorTokenAsync(userId, provider);
// See IdentityConfig.cs to plug in Email/SMS services to actually send the code
await UserManager.NotifyTwoFactorTokenAsync(userId, provider, token);
return true;
//return base.SendTwoFactorCodeAsync(provider);
}

USER_AUTHENTICATION_FAILED Creating Envelope

Currently I'm working with a Node.js integration for DocuSign (https://www.npmjs.com/package/docusign-esign), I made all the test with the sandbox account and worked perfectly, right now I'm trying to use a production account, the login process is fine but when I'm going to create the envelope I get a USER_AUTHENTICATION_FAILED error (even if the first login went without errors). I would like to know if someone has experienced same thing or has an idea of how can I fix this.
This is the code that I took from the docusign-esign to create the envelope:
var loginAccount = new docusign.LoginAccount();
loginAccount = loginAccounts[0];
var accountId = loginAccount.accountId;
var envelopesApi = new docusign.EnvelopesApi();
envelopesApi.createEnvelope(accountId, envDef, null, function (error, envelopeSummary, response)
The account Id is the same retrieved after the login process.
One possible cause could be that your DocuSign account is hosted on na2.docusign.net, na3.docusign.net or eu.docusign.net, while your code uses the default www.docusign.com as a base URL.
The login call will pass even if you use www, however all the subsequent API calls will fail if you are not hitting the exact base URL that corresponds to your production account. You should have received this information as part of the DocuSign Go-Live process (formerly known as API Certification). You can always get the base URL from the login call response.
For Node, here how to get the correct base URL from the login call and set it up to the API Client (lines in bold are likely what is missing in your code):
authApi.login(loginOps, function (err, loginInfo, response) {
if (err) {
return next(err);
}
if (loginInfo) {
// list of user account(s)
// note that a given user may be a member of multiple accounts
var loginAccounts = loginInfo.getLoginAccounts();
console.log('LoginInformation: ' + JSON.stringify(loginAccounts));
var loginAccount = loginAccounts[0];
var accountId = loginAccount.accountId;
var baseUrl = loginAccount.baseUrl;
var accountDomain = baseUrl.split("/v2");
apiClient.setBasePath(accountDomain[0]);
docusign.Configuration.default.setDefaultApiClient(apiClient);
next(null, loginAccount);
}
});

Pusher Window Refresh Issue

i am very new to pusher.com:
I am trying to set up a presence-channel Chat.
Here is my code:
var PresenceChannel = pusher.subscribe('presence-test_channel');
PresenceChannel.bind('pusher:subscription_succeeded', function(members){
$("#chatMembers").empty();
members.each(function(member) {
$("#chatMembers").prepend("<li id='"+member.info.employee_id+"'>"+member.info.customer_id+"</li>");
});
});
PresenceChannel.bind('pusher:member_added',function(member){
$("#chatMembers").prepend("<li id='"+member.info.employee_id+"'>"+member.info.customer_id+"</li>");
});
PresenceChannel.bind('pusher:member_removed',function(member){
$("li#"+member.info.employee_id).remove();
});
Its working as expected.
But i have a problem:
When i refresh one of the opened browser windows, the following events get fired:
PresenceChannel.bind('pusher:member_added',function(member){...
And directly after that,
PresenceChannel.bind('pusher:member_removed',function(member){...
get fired.
So, after a refresh of one window, the user get removed from my list, and
1 second later, the user again is added to the list....
1) Reload 1 browser window
2) The other window triggers 'pusher:member_removed': User removed from List
3) The other window triggers 'pusher:member_added': User added to the list agein
What to do ?
The 2nd window receives a pusher:member_removed because the 1st window has unloaded and the user had therefore left the presence channel. When the 2nd window reloads and the user resubscribes to the presence channel the pusher:member_added is triggered.
This is expected behaviour.
However, Pusher do add a delay to these event in order to try and stop events being triggered in this scenario. In your case it would seem that the delay in not long enough to stop that happening. In your situation there is an FAQ which provides some information about what you can do to work around this:
How can I stop users going offline for an instant when they navigate between pages?
It is simply solved.
Try this.
Pusher dashboard -> Webhooks
and add Webhook url & event type to Presense.
$app_secret = 'YOUR PUSHER SECRET KEY';
$app_key = $request->headers->get('X-Pusher-Key');
$webhook_signature = $request->headers->get('X-Pusher-Signature');
$body = file_get_contents('php://input');
$expected_signature = hash_hmac( 'sha256', $body, $app_secret, false );
if($webhook_signature == $expected_signature) {
// decode as associative array
$payload = json_decode( $body, true );
foreach($payload['events'] as &$event) {
// do something with the event
if ($event['name'] == 'member_added') {
// do process user joind & trigger message
$this->setAddMember($event);
} elseif ($event['name'] == 'member_removed') {
// do process user out & trigger message
$this->setRemoveMember($event);
}
}
header("Status: 200 OK");
}
else {
header("Status: 401 Not authenticated");
}
More detailed information see document this.
https://pusher.com/docs/webhooks

Resources