Recipe - Passwordless Login Prep
Skill level: Intermediate
Organization: The Father's House
Requires Rock: 1.15.0
{# strip images & classes from the HTML but otherwise leave structure #}
To avoid, really just reduce, instances where a person will
login to our external site utilizing the Passwordless login block, introduced
in v15, with multiple person records attached to their phone number, we took a
2 prong approach:
1.
Prompt users to validate their contact
information and “validate” their phone number.
2.
Create an Job that fires workflows to clean up
the duplicate phone numbers every night
The goal is to keep clean data, but also to promote a safer
environment for our users & our data. While our approach makes some
assumptions about the “owner” of the phone numbers, this is all adjustable
& configurable to your specific organization & requirements. Some of
the assumptions we make may come back to bite us, but our hope is that
the assumptions we make are thought out & the safest ones we can make.
In this Recipe I’m only explaining the process &
providing the supporting documents & workflow imports at the bottom of this
Recipe. This recipe would get to be really long if I walked through all of the
steps, but I’m happy to answer any questions y’all have in the comments below
or in RocketChat.
So now with way too much ado… let’s get going!
Process Preparations
To follow along with our process, you’ll need to create 2
person attributes & install 2 plugins:
Contact
Information Validation:
-
Contact Info Updated Date: This will store the
date when the user last updated/confirmed their information.
-
Contact Info Update – Delay: This will store the
date when the person last skipped validating their information.
Duplicate Phone Number Removal:
-
South East Chistian’s - Workflow Launcher
-
Blue Box Moon’s - Workflow Stimpack
Contact Information
Validation
In addition to being a tongue twister, Contact Information
Validation, is our first line of defense. We’re hoping that users will do some
of our work for us. I don’t know about your users, but our users love to update
& correct their own data… sometimes too much, so an assumption we’re making
is that users will interact with our “pop-up” correction form. In the form we
show their data give them multiple “outs” so their not trapped, and try to make
the process easy & simple. Here’s our process & how we built it.
The process starts by evaluating the two person attributes
we created in the preparation step. We have our process setup so if 4 months
have passed since the user validated their information it’s been 7 or
more days since they skipped this process, we redirect their traffic to the form & passing the original
destination URL into the workflow for later on in the process. The workflow
starts by presenting the Current Person’s data to them & asking if they’d
like to Update Info, Confirm the Info, or Skip. I’ll give a brief overview of
all the paths, but will start with the shortest & end with the longest.
Confirm
Upon confirmation of the data, the user is then sent on their way to their
original destination. The workflow then in the background updates their
Information Confirmation person attribute. (In the near future we’re going to ask
these people to validate their number, but in this initial deployed version
we’re just moving them on.)
Skip
When the user clicks skip they’re moved on their way to the
original destination. This process is actually a bit more involved than just a
redirect, we actually launch a separate workflow which handles the redirect
& updates the Skip Information Confirmation person attribute & then also
redirects them.
We created a separate workflow that’s launched when the user clicks skip
because we wanted the skip in the top right corner of the page & it’s the
easiest way to accomplish that.
Update
This is where the “magic” of this workflow lives. We get going by showing the
user editable fields to update their phone and email address, (If they have an
email address that contains “@tfh.org” which is our email domain, we route them
to a different form that explains they can’t change their email & allow
them to update their phone number) Once they’ve completed updating their
information we check their phone number to evaluate if the number they entered
is anywhere in the PhoneNumber table, if it exists we take them to the number validation step where we generate
a randomized 6 character code, once they validate their number the path is the
same as if their number wasn’t updated. After number validation or if their
number didn’t require validation according to our process, the data is updated
& the user to sent on their way to the original destination.
There’s a few changes I’d like to make, but I currently do
not have the time to implement these changes.
-
I’d like to ask the user to validate their
number if they confirm the data in step 1, if the number is found more than
once in the PhoneNumber table.
-
Upon updating their information, if they don’t
change their phone number, I’d like to ask them to validate their number, if
there’s a duplicate in the database.
These aren’t hard to do, but require a little bit of
reworking this process, since I built it to be as unintrusive as possible, but
we’ve since realized we can ask for validation & don’t need to force
validation in a few instances.
Duplicate Phone Number
Removal
This is where the assumptions start to get a bit risky, but
we’ve made the safest ones we can think of. We start by having a job, which I’ll
explain at the end of this section, that finds any phone number occurring more
than once in the PhoneNumber table & creates a single row for each phone
number ordered from oldest to newest. We capture the Phone Number & the Person
Id for each of the duplicate numbers. Once created, each row is then passed
into a workflow that takes the string & pops the first person off the
string. The workflow then passes the remaining string to a Blue Box Moon “For
Each” action from the Workflow
Stimpack. It splits the remaining Person Id & Number & an Activity
is launched for each. The Activity removes the number from the account
utilizing the Core Phone Number Update action, to set each instance of the
number to ‘Null’. We leave a note on each person that is updated indicating
when this change occurred & who is the “owner” of the number.
The job that initiates this whole process is where some of
the magic happens. The job is the “Workflow Launch” job type that’s installed
from the South East Christian “Workflow Launcher” plug-in.
I have it set to run each morning at 1am, it’s utilizing the following SQL
Query:
SELECT STRING_AGG(CONCAT(sub1.[PersonId],':',sub1.[NumberTypeValueId]),',') as RawNumberString
FROM (
SELECT top 1000000 n.*
FROM [PhoneNumber] n
INNER JOIN [Person] p on p.[Id]=n.[PersonId]
ORDER BY n.CreatedDateTime ASC,p.AgeClassification ASC
)sub1
GROUP BY sub1.[NumberFormatted]
HAVING COUNT(sub1.[NumberFormatted]) > 1
While this section is shorter than the previous, it’s the
one that should give you pause & make you think through if this is the right move for
your Organization. We’ve evaluated the risks & have deemed them acceptable
for the added security, but it might not be the case for your Organiziation.
One of the major issues that could arise is at Check-In. If a number gets
disassociated from an account, it could cause issues where a family won’t show
up if the number is removed. We’ve looked over our data in some quick spot
checking & didn’t see any cases where this would happen, but we’re prepared
for some instances of it. Before taking this step I highly recommend
talking with your teams & staff to make them aware of some changes that may
cause issues. We messaged it as “security updates” may cause some changes to phone
numbers, since we’re removing duplicate phone numbers.
Conclusion
This process was the right one for us… or at least we hope
it is. It might not be perfect for your organization, but hopefully it’s
helpful in getting you thinking through ways to improve your Passwordless logins!
Again, if you have any questions please feel free to comment
under this recipe or message me in RocketChat! I’m always happy to help.
Shared Assets & Files:
https://www.dropbox.com/sh/yu61yuyhvvtcolt/AACOnxAcFVQ45sLdrsLFTzzma?dl=0