Creating an Asterisk "application" to send GET requests from an endpoint via Phone Prompt - asterisk

To start off, I'd like to state that this is my first dive into Asterisk related applications, and that I'm mostly a web developer.
My workplace uses an MSP that installed Asterisk/FreePBX to manage our phone systems. The GUI is pretty intuitive and after reading and getting a bit lost I figured I'd come here and see how to go about setting this up.
I was tasked with building a simple application to reset user passwords through both a web interface (completed) and a phone interface - by dialing a number, dialing their ID card #, and then having their password reset. I'm a Systems Administrator and have access to all necessary applications, servers, etc. I can pick things up fairly easy and I was told I'd have enough time to figure this out and get it done.
This is what I need in terms of pseudocode when the user calls a specific extension:
recording('pwResetCardID'); // Play a "Please enter your ID # to reset PW" greeting.
function getCardID() {
cardID = input(); // Input 4-5 digits using the dialpad and save it to a var.
verify = get('http://some.site/endpoint/cardid/'.$cardid); // Send a GET request.
if verify { // If we got a successful response (200)
recording('pwChanged'); // Tell the user their password has changed
} else { //
recording('errorCardID'); // Otherwise tell them to try again
getCardID(); // Recur the function.
}
}
getCardID();
If the cardID is valid, their PW is changed on the other end of my node.js application, and I simply need the GET request to be sent out and the user notified of the success (or failure)

You can start from doc describing asterisk dialplan
Probably need use func_CURL, Read application, Playbavk and Goto
You need put new dialplan in extensions_custom.conf and setup use it via custom apps module

Related

SignalR connected client in Clients.User(..) shouldn't exist

In my SignalR hub, I use the following method to check whether a user has an active connection:
var receivingClient = Clients.User(receiver);
if (receivingClient != null)
{
But I also track the online users manually over OnConnected \ OnDisconnected (in a ConcurrentDictionary). Now even when I shut down everything and start the server from scratch (e.g. IISExpress from VS), the above code part returns a result for a connection that doesn't exist.
Let's say I send from User A to user B. I start the server, go online with user A, then send a message to B: The above code returns a Microsoft.AspNetCore.SignalR.Internal.UserProxy<mySite.Services.ChatHub>.
I don't get it. Is it wrong to check for existing client connections with a null check? Should I exclusively rely on my manual tracking?
Thanks for some insight!
(PS: This is all on the same server - no load balancing / sharding)
Clients.User(receiver) returns a type that is used to invoke methods for the given user. It doesn't have anything to do with whether the user you pass in exists or not.
Is it wrong to check for existing client connections with a null check? Should I exclusively rely on my manual tracking?
Yes. Use manual tracking.

Check if a user is currently online to meteor server

I'd like to determine if a user is currently "online" or connected to the Meteor server.
I need this information before I send the user message, If the user is not connected I'd like to send the message via email.
I know that for traditional web applications that are totally state-less the definition of "online" use is a bit not clear but since modern web frameworks rely on websocket, a user is supposed to be online if a websocket is open.
The question is does Meteor include a method to determine if a user is connected or not?
Summarized: yes, there is such a mechanism.
There are for example package, that store the active login connections of the users with the meteor server and make them available either via an own collection or as part of the user profile.
See: https://github.com/dburles/meteor-presence
(Creates a new collection, called Presences)
or https://github.com/dan335/meteor-user-presence/
(Creates a user's profile entry, called presence. However, has also a collection to store and update the information in the background)
or https://github.com/mizzao/meteor-user-status
(Thanks to blueren in the comments)
Code example (from the first listed package)
Meteor.onConnection(function(connection) {
// console.log('connectionId: ' + connection.id);
Presences.insert({ _id: connection.id });
connections[connection.id] = {};
tick(connection.id);
connection.onClose(function() {
// console.log('connection closed: ' + connection.id);
expire(connection.id);
});
});
If you don't want to rely on the packages you may make use of that mechanism yourself.
See: https://docs.meteor.com/api/connections.html#Meteor-onConnection

Guidelines for robust synchronisation of mobile client (iOS, Swift) with Realm Object Server

I have used the techniques in the RealmTask tutorial (https://realm.io/docs/tutorials/realmtasks/ ) to get a demonstration of synchronisation with the Realm Object Server working. However, as mentioned in realm mobile platform, how to connect while offline? , it is difficult to find design guidelines on realising a robust app in the presence of intermittent network connectivity. For example, the network might not be available when the app is first run, and in the tutorial example I think the login attempt would just time out after say 30 seconds.
From various sources, I have tried to outline an implementation approach on the client and have come up with the following:
=============================================================
At start-up of app
Create login credentials with
SyncCredentials.usernamePassword()
Check whether user credentials already exist using
SyncUser.all
If so, get the correct user using the appropriate key (UserId)
If a user is obtained, get the Realm configuration using
realmConfiguration = Realm.Configuration(SyncConfiguration(user, realmURL))
Attempt a log-in with
SyncUser.logIn with SyncCredentials
On completion, put the following on the main DispatchQueue (async)
realmConfiguration = Realm.Configuration(SyncConfiguration(user, realmURL))
if not logged in, repeat login attempts every N minutes until successful? E.g. to handle the situation when the network is unavailable when the app is started, but then becomes available?
Launch the rest of the app, making realmConfiguration available.
However, only access the Realm if realmConfiguration has been set up. Design the app so that it handles the scenario of realmConfiguration not being set up.
=============================================================
Is the above approach sensible, or is there a better solution?
Katsumi from Realm here. Our RealmTasks demo application may help you.
https://github.com/realm-demos/realm-tasks/tree/master/RealmTasks%20Apple
First, check whether the user has logged in or not at launched the app.
if configureDefaultRealm() {
window?.rootViewController = ContainerViewController()
window?.makeKeyAndVisible()
} else {
window?.rootViewController = UIViewController()
window?.makeKeyAndVisible()
logIn(animated: false)
}
https://github.com/realm-demos/realm-tasks/blob/master/RealmTasks%20Apple/RealmTasks%20iOS/AppDelegate.swift#L35
If the user has been logged in before, you can use user object that was cached before. (SyncUser.current or SyncUser.all)
If there is no cached user object (The user is the first time to use the app, or the user re-installs the app), show login view to signing up/in.
The former case (Use the cached user object) doesn't require network access, so you don't need to care about the offline situation.
The latter case (The user should signing up/in) requires network access, in that case, the best practice depends on the specification of the app. It is enough to show a just alert view that indicates requiring network for some apps, or use standalone Realm and then migrate synced realm after the app will be online.

Possibility for only currently connected (not authenticated) and admin user to read and write on certain location

Is there any way to write a security rule or is there any other approach that would make possible only for currently connected (not authenticated) user to write/read certain location - admin should also be able to write/read?
Can a rule be written that disallows users to read of complete list of entries and let them read only entry that matches some identifier that was passed from client?
I'm trying to exchange some data between user and Node.js application through Firebase and that data shouldn't be able to read or write by anyone else other than user and/or admin.
I know that one solution would be that user requests auth token on my server and uses it to authenticate on Firebase and that would make it possible to write rule which prevents reads and writes. However, I'm trying to avoid user connecting to my server so this solution is not first option.
This is in a way session based scenario which is not available in Firebase but I have
some ideas that could solve this kind of problem - if implemented before session management:
maybe letting admin write into /.info/ location which is observed by client for every change and can be read only by active connection - if I understood correctly how .info works
maybe creating .temp location for that purpose
maybe letting admin and connected client could have more access to connection information which would contain some connection unique id, that can be used to create location with that name and use it inside rule to prevent reading and listing to other users
Thanks
This seems like a classic XY problem (i.e. trying to solve the attempted solution instead of the actual problem).
If I understand your constraints correctly, the underlying issue is that you do not wish to have direct connections to your server. This is currently the model we're using with Firebase and I can think of two simple patterns to accomplish this.
1) Store the data in an non-guessable path
Create a UUID or GID or, assuming we're not talking bank level security here, just a plain Firebase ID ( firebaseRef.push().name() ). Then have the server and client communicate via this path.
This avoids the need for security rules since the URLs are unguessable, or close enough to it, in the case of the Firebase ID, for normal uses.
Client example:
var fb = new Firebase(MY_INSTANCE_URL+'/connect');
var uniquePath = fb.push();
var myId = uniquePath.name();
// send a message to the server
uniquePath.push('hello world');
From the server, simply monitor connect, each one that connects is a new client:
var fb = new Firebase(MY_INSTANCE_URL+'/connect');
fb.on('child_added', newClientConnected);
function newClientConnected(snapshot) {
snapshot.ref().on('child_added', function(ss) {
// when the client sends me a message, log it and then return "goodbye"
console.log('new message', ss.val());
ss.ref().set('goodbye');
});
};
In your security rules:
{
"rules": {
// read/write are false by default
"connect": {
// contents cannot be listed, no way to find out ids other than guessing
"$client": {
".read": true,
".write": true
}
}
}
}
2) Use Firebase authentication
Instead of expending so much effort to avoid authentication, just use a third party service, like Firebase's built-in auth, or Singly (which supports Firebase). This is the best of both worlds, and the model I use for most cases.
Your client can authenticate directly with one of these services, never touching your server, and then authenticate to Firebase with the token, allowing security rules to take effect.

QtMobility bearer management

I'm creating a Qt Symbian application and need to connect to internet. In some way I need to let the user choose a connection ONCE when the app starts or use the DEFAULT connection if that is enabled.
Before I just used qt_SetDefaultIap() to set the connection on start. It worked perfect but now I need to use QtMobility instead. I have tried the following in QMainWindow when my app starts:
QNetworkConfigurationManager manager;
const bool selectIap = (manager.capabilities()& QNetworkConfigurationManager::CanStartAndStopInterfaces);
QNetworkConfiguration defaultIap = manager.defaultConfiguration();
if(!defaultIap.isValid() && (!selectIap && defaultIap.state() != QNetworkConfiguration::Active))
{
// let the user know that there is no access point available
}
session = new QNetworkSession(defaultIap,this);
session->open();
But there must be something I'm missing as the application always asks the user to choose connection each time it uses internet not just once as I want. And even if I choose a connection the application asks three times. EDIT: It works on Nokia 5800 but not on N97.
This seems to be a problem for many people as it has been discussed before:
http://discussion.forum.nokia.com/forum/showthread.php?196396-how-to-use-QNetworkConfigurationManager-to-handle-access-point
http://discussion.forum.nokia.com/forum/showthread.php?199401-How-to-use-bearer-management-to-select-access-point
http://discussion.forum.nokia.com/forum/showthread.php?199472-How-can-I-set-the-best-one-access-point-as-default
Any ideas on how to get this working?
if your phone settings are set as 'Always ask' in (5800) Menu -> Settings -> Destinations -> Options -> Default connection, then QNetworkConfigurationManager.defaultConfiguration() will return the UserChoice configuration, which will always popup a query.
If you wish to control which access point is really used, then you could enumerate/list the configurations (QNetworkConfigurationManager::allConfigurations(), choose the one you want, and then create a QNetworkSession based on it and call QNetworkSession::open(). After that if you instantiate and use e.g. QNetworkAccessManager to perform web queries, they should use that configuration "automatically".

Resources