How to properly configure MAIL_URL? - javascript

The follwoing smtp url giving me an error
process.env.MAIL_URL="smtp://mail_name#outlook.com:Password#smtp.outlook.com:457";
What am I doing wrong?

For starters, your issue is that your user name (and perhaps your password) contain a character that cannot be placed in a URL as-is, and therefore needs to be encoded.
I want to take this opportunity to provide a little more in-depth answer to the issue of configuring the MAIL_URL environment variable.
If you simply need a quick string that will work, do:
process.env.MAIL_URL="smtp://"+encodeURIComponent("mail_name#outlook.com")+":"+encodeURIComponent("Password")+"#smtp.outlook.com:457";
Also take into account that you may need to use smtps for secure connection, and if it uses TLS, your connection may fail.
I recommend to read the rest if you need anything more robust.
URL
A URL has the following structure:
scheme:[//[user[:password]#]host[:port]][/path][?query][#fragment]
The scheme would be either smtp or smtps (for secure connection), and in this scenario you will also set the user, password, host and (most likely) port.
Each of the parts needs to be encoded in a way that is suitable for use in a URL, but since hosts (domains) are normally already appropriate, you only need to make sure that your user name/password are encoded.
In EcmaScript, encodeURIComponent can be used for this.
MAIL_URL and node environment variables
Meteor checks the value of process.env.MAIL_URL when sending an email.
process.env is populated by node.js with the environment variables available to it on startup.
It is possible to add properties to it on runtime, so setting process.env.MAIL_URL before sending an email will work. However, you should do so wisely to prevent your secrets from leaking.
I would suggest 2 methods for setting it up, either using settings.json or using the environment variable itself.
using settings.json
Create a json file in your project. It is highly recommended not to commit it into source control with the rest of your code.
for example: config/development/settings.json
{
"smtp": {
"isSecure": true,
"userName": "your_username",
"password": "your_password",
"host": "smtp.gmail.com",
"port": 465
}
}
And somewhere in your server code:
Meteor.startup(function() {
if (Meteor.settings && Meteor.settings.smtp) {
const { userName, password, host, port, isSecure } = Meteor.settings.smtp;
const scheme = isSecure ? 'smtps' : 'smtp';
process.env.MAIL_URL = `${scheme}://${encodeURIComponent(userName)}:${encodeURIComponent(password)}#${host}:${port}`;
}
});
Then you can run Meteor with the --settings switch.
meteor run --settings config/development/settings.json
using an environment variable
You can set the environment variable to the encoded string. If you want a utility script (for zsh on *nix) that will convert it (depends on node):
mail_url.sh
#!/bin/zsh
alias urlencode='node -e "console.log(encodeURIComponent(process.argv[1]))"'
ENC_USER=`urlencode $2`
ENC_PASS=`urlencode $3`
MAIL_URL="$1://$ENC_USER:$ENC_PASS#$4"
echo $MAIL_URL
which can be used as follows:
$ chmod +x mail_url.sh
$ MAIL_SCHEME=smtps
$ MAIL_USER=foo#bar.baz
$ MAIL_PASSWORD=p#$$w0rd
$ MAIL_HOST=smtp.gmail.com:465
$ export MAIL_URL=$(./mail_url.sh $MAIL_SCHEME $MAIL_USER $MAIL_PASSWORD $MAIL_HOST)
$ echo $MAIL_URL
smtps://foo%40bar.baz:p%4015766w0rd#smtp.gmail.com:465

Related

How to get org_id as part of access token using Auth0?

I am try to get get org_id While generating using UserNamePassword authentication?
I have added rule as below
context.accessToken[namespace + 'org'] = context.organization;
After generating access token I have decoded it and I couldn't find org_id in json response
Does namespace have a valid value e.g. http://www.myexample.com/org_id? If not it might be getting silently excluded
By default, Auth0 always enforces namespacing; any custom claims with
non-namespaced identifiers will be silently excluded from tokens and
silently ignored in Actions and Rules.
https://auth0.com/docs/secure/tokens/json-web-tokens/create-namespaced-custom-claims
You can debug these rules quite easily by adding some debug statements to your rule e.g. console.log(namespace + 'org') and installing and running the Real-time Webtask Logs extension
Finally, here's a full Rule example for adding a custom claim to access token:
function addAttributes(user, context, callback) {
const namespace = configuration.Namespace;
context.accessToken[`${namespace}org_id`] = 'test';
callback(null, user, context);
}
note: configuration.Namespace is a rule setting with a value of something like http://www.myexample.com/

Microsoft Graph - Delete Access Package Assignment

I'm using Microsoft Graph API Beta version to delete an access package. However, for deleting an access package, I need first to remove all its assignments.
For doing this, I found on the official doc the accessPackageAssignment object (https://learn.microsoft.com/en-us/graph/api/resources/accesspackageassignment?view=graph-rest-beta).
When I perform a get request on the assignment:
result = azureAdBeta.get('/identityGovernance/entitlementManagement/accessPackageAssignments/' + accessPackageAssignmentId)
the response is successful:
{'#odata.context': 'https://graph.microsoft.com/beta/$metadata#identityGovernance/entitlementManagement/accessPackageAssignments/$entity',
'accessPackageId': 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx',
'assignmentPolicyId': 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx',
'assignmentState': 'Delivered',
'assignmentStatus': 'Delivered',
'catalogId': 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx',
'expiredDateTime': None,
'id': '2ad2eb61-9baa-45b9-a700-bfef425d7aef',
'isExtended': False,
'schedule': {'expiration': {'duration': None,
'endDateTime': '2022-01-20T23:00:00Z',
'type': 'afterDateTime'},
'recurrence': None,
'startDateTime': '2021-12-15T11:16:04.663Z'},
'targetId': 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'}
However, when I perform a delete request:
result = azureAdBeta.delete('/identityGovernance/entitlementManagement/accessPackageAssignments/' + accessPackageAssignmentId)
I get the following error:
{'error': {'code': '',
'innerError': {'client-request-id': 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx',
'date': '2021-12-15T11:32:37',
'request-id': 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'},
'message': 'No HTTP resource was found that matches the request URI '
"'https://igaelm-asev3-ecapi-neu.igaelm-asev3-environment-neu.p.azurewebsites.net/api/v1/accessPackageAssignments('xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx')'."}}
I suppose this error is due to fact that in doc no delete method is mentioned for the accessPackageAssignment object.
So how can I delete an access package assignment via Microsoft Graph?
• You can remove an Access package assignment through Microsoft graph powershell module in the following way: -
First view all the access package assignments through the below powershell command -
‘ Connect-MgGraph -Scopes "EntitlementManagement.Read.All"
Select-MgProfile -Name "beta"
$accesspackage = Get-MgEntitlementManagementAccessPackage -DisplayNameEq "Marketing Campaign"
$assignments = Get-MgEntitlementManagementAccessPackageAssignment -AccessPackageId $accesspackage.Id -ExpandProperty target -All -ErrorAction Stop
$assignments | ft Id,AssignmentState,TargetId,{$_.Target.DisplayName} ’
The above command will display all the assignments for the access package as stated above which correspond to the stated display name. Once, all the access package assignments for the stated access package are displayed, execute the below command to remove the access package assignment for the concerned access package by entering the correct access packageID. Also, enter the correct targetID(objectID of the user/group/resource) of the assignment to be removed.
‘ Connect-MgGraph -Scopes "EntitlementManagement.ReadWrite.All"
Select-MgProfile -Name "beta"
$assignments = Get-MgEntitlementManagementAccessPackageAssignment -Filter
"accessPackageId eq '9f573551-f8e2-48f4-bf48-06efbb37c7b8' and
assignmentState eq 'Delivered'" -All -ErrorAction Stop
$toRemove = $assignments | Where-Object {$_.targetId -eq '76fd6e6a-c390-
42f0-879e-93ca093321e7'}
$req = New-MgEntitlementManagementAccessPackageAssignmentRequest -
AccessPackageAssignmentId $toRemove.Id -RequestType "AdminRemove" ’
This will remove the access package assignment for the concerned access package.
Note: - You will have to install the Microsoft Graph Identity Governance module in powershell for executing the above commands. To install the module, please run this command in elevated powershell – ‘Install-Module -Name Microsoft.Graph.Identity.Governance’
Also, you can remove the access package assignment through Microsoft Graph from an application JSON file. To do so, refer the following link and replace the value of "requestType": "AdminAdd" to "requestType": "AdminRemove"
https://learn.microsoft.com/en-us/graph/api/accesspackageassignmentrequest-post?view=graph-rest-beta&preserve-view=true&tabs=http#request
Please refer the below link also for reference: -
https://learn.microsoft.com/en-us/azure/active-directory/governance/entitlement-management-access-package-assignments#remove-an-assignment-programmatically

Using ssh fingerprint in ssh2-sftp-client

Ok, this might need a little bit of explaination up front.
I am currently working on an automation project using node-red.
I want to upload and download files from an remote server using ssh. For this tasks I use this node-red package called node-red-contrib-sftpc. I rewrote the library a little bit, so that I can hand over some credentials for the sftp connection, via the payload which is handed over to the node.
To establish an connection the sftp.connect method of the ssh2-sftp-client is used:
await sftp.connect({
host: node.server.host,
port: node.server.port,
username: node.server.username,
password: node.server.password});
There you can find in the documentation that you can provide connect with the parameters hostHash and hostVerifier. The documentation of the ssh2 model, on which the ssh2-sftp-client is based, states that:
hostHash - string - Any valid hash algorithm supported by node. The host's key is hashed using this algorithm and passed to the hostVerifier function as a hex string. Default: (none)
hostVerifier - function - Function with parameters (hashedKey[,
callback]) where hashedKey is a string hex hash of the host's key for
verification purposes. Return true to continue with the handshake or
false to reject and disconnect, or call callback() with true or false
if you need to perform asynchronous verification. Default:
(auto-accept if hostVerifier is not set)
So here is my problem: How do I write the hostVerifier function? I want to pass hashedKey and also fingerprint, so that I can return true or false, when the handshake worked out or not.
I want to check, if the given server key fingerprint is the "right" one and that I connect to the correct server.
So far as I understood the second parameter, will be a callback function, but I do not know how to use that, so that it will verify the handshake.
This was my try, or at least how I tried to do it.
node.server.hostVerifier = function (hashedKey, (hashedKey, msg.fingerprint)=> {
if (hashedKey = msg.fingerprint) return true;
else return false
}){};
await sftp.connect({
host: node.server.host,
port: node.server.port,
username: node.server.username,
password: node.server.password,
hostHash: 'someHashAlgo',
hostVerifier: node.server.hostVerifier,});
I know that this is completely wrong, but I am about to get crazy, because I have no idea, how to proper check the ssh host key fingerprint.
So I found a solution myself and want to share it with you.
I defined an arrow function as the hostVerifier function, which takes implicite the value of the fingerprint through the msg.fingerprint variable. I only do this, if node.server.fingerprint has an value. So if I do not have an fingerprint at hand, the connection will still established.
node.server.fingerprint = msg.fingerprint;
if(!!node.server.fingerprint){
node.server.hostHash = 'md5';
node.server.hostVerifier = (hashedKey) => {
return (hashedKey === msg.fingerprint) ;};
node.server.algorithms = {serverHostKey: ['ssh-rsa'],};
};
For that I also declare my node.server.alogrithms. With that it was a little bit of try and error.
So I put everything together here:
await sftp.connect({
host: node.server.host,
port: node.server.port,
username: node.server.username,
password: node.server.password,
hostHash: node.server.hostHash,
hostVerifier: node.server.hostVerifier,
algorithms: node.server.algorithms,
});

Azure Functions - Value cannot be null. (Parameter 'connectionString')

I was trying to setup simple Azure Function to read a XML stream and sync it back to the database. My plan was to use a Time Trigger to execute the function once per day.
Howerver, things are not looking great. I'm getting the following error, even if I don't use a database:
[Error] Executed 'Functions.<func-name>' (Failed, Id=<func-id>, Duration=1ms)Value cannot be null. (Parameter 'connectionString')
I'm currently trying to execute the following function:
module.exports = async function(context, req) {
context.res = {
body: "Success!"
};
};
Same result. I can't run it.
I've added a Connection String to the Configuration -> Connection Strings (I thought that I've missed that, based on the message).
My functions.json file looks like:
{
"bindings": [
{
"name": "myTimer",
"type": "timerTrigger",
"direction": "in",
"schedule": "0 0 * * * *"
},
{
"type": "http",
"direction": "out",
"name": "res"
}
]
}
I've also tried running a C# function - same result.
So, what have I missed?
Logging from Microsoft to it's finest.
AzureWebJobsStorage App Setting was missing.
Solution:
Create Storage account (or use existing one)
Go to your Function App's Configuration
Add AzureWebJobsStorage with a connection string to your Storage account (can be found at Storage Account Overview -> Access Keys)
In my case the error was Microsoft.Extensions.Configuration.AzureAppConfiguration value cannot be null: parameter (connectionString)
This happened because I has installed Microsoft.Extensions.Configuration.AzureAppConfiguration in my Function to DI the configuration into my main function. The Startup.cs line string cs = Environment.GetEnvironmentVariable("MyDifferentConnectionString"); was not able to find an environment variable for MyDifferentConnectionString, so this needed to be added to the Function config.
Go to App Configuration (or create one)
Access Keys (under Settings)
Copy Connection String
Go to your Function
Configuration (under Settings)
Add a new Application Settings with the name of your environment variable and paste the value
Save and restart your Function

MeteorJS what to put under /server folder?

I'm following the Discover Meteor book and the book suggets put js file under /collections folder. The js file defines server side methods:
Meteor.methods({
post: function(postAttributes) {
var user = Meteor.user();
var postWithSameLink = Posts.findOne({url: postAttributes.url});
// ensure the user is logged in
if (!user)
throw new Meteor.Error(401, "You need to login to post new stories");
// ensure the post has a title
if (!postAttributes.title)
throw new Meteor.Error(422, 'Please fill in a headline');
// check that there are no previous posts with the same link
if (postAttributes.url && postWithSameLink) {
throw new Meteor.Error(302,
'This link has already been posted',
postWithSameLink._id);
}
// pick out the whitelisted keys
var post = _.extend(_.pick(postAttributes, 'url', 'title', 'message'), {
userId: user._id,
author: user.username,
submitted: new Date().getTime(),
commentsCount: 0,
upvoters: [],
votes: 0
});
var postId = Posts.insert(post);
return postId;
},
});
Well, in that case, isn't the whole logic accessible to public since Meteor gathers all JavaScript files in your tree, with the exception of the server, public, and private subdirectories, for the client.?
Is this a concern?
What should I put to server folder?
There are many server-only things that might go in that folder – subscriptions, allow rules, cron jobs etc.
The server folder is the only place from which your code is not visible to general public. Naturally, it's the place where you should put your security-related code: allow / deny rules, accounts configuration etc. If you talk to an external API and want to place your access keys in code, /server folder is the only acceptable place to do so.
Putting your server-side logic in an accessible folder is not a critical issue, as server-side code cannot be altered from the client. The only security concern here is that someone might study your code and find a breech if you did a shortcut somewhere. Also, you're clogging the connection with code that's not needed in the client.
I'd also say that most methods should go in /server, but that depends on what you need. Making methods code accessible on the client allows to take advantage of latency compensation (here, third paragraph below the example), but you need to make sure yourself that the client-side simulation doesn't produce side effects that would interfere with the actual (server-side) modifications.
In your case, you can put this method in /collections or /model folder and don't worry about this. You can also put it in /server and things will work as well.

Categories