Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 69740e2

Browse filesBrowse files
committed
Add magic email link / passwordless authentication demo for Firebase and Angular 7.1.1.
1 parent 7854cbd commit 69740e2
Copy full SHA for 69740e2
Expand file treeCollapse file tree

20 files changed

+11432
-0
lines changed
Open diff view settings
Collapse file

‎README.md‎

Copy file name to clipboardExpand all lines: README.md
+1Lines changed: 1 addition & 0 deletions
  • Display the source diff
  • Display the rich diff
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ with.
1010

1111
## My JavaScript Demos - I Love JavaScript!
1212

13+
* [Using Magic Email Links To Authenticate Users With Firebase 5.7.0 In Angular 7.1.2](https://bennadel.github.io/JavaScript-Demos/demos/firebase-email-auth-angular7/)
1314
* [Using A "Drag Shield" To Block Mouse Events During A Drag-And-Drop Workflow In Angular 7.1.2](https://bennadel.github.io/JavaScript-Demos/demos/drag-shield-angular7/)
1415
* [ngOnChanges() Life Cycle Hook Only Gets Invoked If Calling Context Actually Provides Input Bindings In Angular 7.1.1](https://bennadel.github.io/JavaScript-Demos/demos/ng-on-changes-no-inputs-angular7/)
1516
* [Strict Mode Settings In JavaScript Are Scoped To The Script Tag](https://bennadel.github.io/JavaScript-Demos/demos/use-strict-scoping/)
Collapse file
+4Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
2+
# Now that we're using Webpack, we can install modules locally and just ignore
3+
# them since the assets are baked into the compiled modules.
4+
node_modules/
Collapse file
+122Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
<!--
2+
For the sake of simplicity, we are going to keep this demo as SIMPLE AS POSSIBLE.
3+
Each phase of the passwordless / magic email link authentication workflow will be
4+
modeled by one of the following "views".
5+
-->
6+
<div [ngSwitch]="view">
7+
8+
<!--
9+
PHASE ONE: Status Unknown - after we initialize the Firebase client instance, we
10+
don't know the user's authentication status right away. The status is reported
11+
asynchronously. As such, we want to represent the app as "loading" until will,
12+
at the very least, know whether or not the user is logged-in.
13+
-->
14+
<div *ngSwitchCase="( 'loading' )">
15+
16+
<p>
17+
<em>Loading....</em>
18+
</p>
19+
20+
</div>
21+
22+
<!--
23+
PHASE TWO: Not Logged-In - once we know that the user does not have a Firebase
24+
user session, we can present them with a login form. Since we are using the magic
25+
email link / passwordless authentication, the user only needs to provide their
26+
email address, to which we will send a one-time-use magic email link.
27+
-->
28+
<div *ngSwitchCase="( 'login' )">
29+
30+
<h2>
31+
Login With Magic Email Link
32+
</h2>
33+
34+
<div *ngIf="errorMessage" class="error">
35+
{{ errorMessage }}
36+
</div>
37+
38+
<form (submit)="sendMagicLink( emailInput.value.trim() ); $event.preventDefault()">
39+
<strong>Email:</strong>
40+
<input #emailInput type="text" size="25" />
41+
<button type="submit">Send Magic Email Link</button>
42+
</form>
43+
44+
</div>
45+
46+
<!--
47+
PHASE TWO (continued): Email Link Sent - once the magic email link has been sent,
48+
the user will need to go do their email client (ex, Gmail) and either click on
49+
the link we sent her; or, copy-paste the link back into this browser.
50+
-->
51+
<div *ngSwitchCase="( 'sent' )">
52+
53+
<h2>
54+
Login With Magic Email Link
55+
</h2>
56+
57+
<p>
58+
<strong>We've sent you an email</strong> - in order to complete your login,
59+
please click on the link in the email; or, copy-paste it back into this
60+
browser navigation bar.
61+
</p>
62+
63+
<p>
64+
<a (click)="setView( 'login' )">Return to login</a>
65+
</p>
66+
67+
</div>
68+
69+
<!--
70+
PHASE THREE: Pending Authentication - Firebase has sent out the one-time-use
71+
magic email link for passwordless authentication. The user now needs to confirm
72+
the email address associated with the link (as a security precaution to prevent
73+
session fixation attacks).
74+
// --
75+
NOTE: If we store the user's email address in something like LocalStorage, then
76+
we can implicitly process this step without asking the user to do anything.
77+
-->
78+
<div *ngSwitchCase="( 'authenticate' )">
79+
80+
<h2>
81+
Complete Passwordless Authentication
82+
</h2>
83+
84+
<div *ngIf="errorMessage" class="error">
85+
{{ errorMessage }}
86+
</div>
87+
88+
<form (submit)="authenticate( emailInput.value.trim() ); $event.preventDefault()">
89+
<strong>Confirm Email:</strong>
90+
<input #emailInput type="text" size="25" />
91+
<button type="submit">Sign-In</button>
92+
</form>
93+
94+
<p>
95+
<a (click)="setView( 'login' )">Return to login</a>
96+
</p>
97+
98+
</div>
99+
100+
<!--
101+
PHASE FOUR: Authenticated User - once the user confirms their email address, we
102+
are able to process the email-link URL. This will result in a Firebase use
103+
session. This session is long-lived by default (but can be adjusted); which makes
104+
it important to provide an explicit sign-out call-to-action.
105+
-->
106+
<div *ngSwitchCase="( 'home' )">
107+
108+
<h2>
109+
Welcome <code>{{ user.email }}</code>.
110+
</h2>
111+
112+
<p>
113+
What a glorious day to be using Angular 7 and Firebase!
114+
</p>
115+
116+
<p>
117+
<a (click)="signout()">Sign-Out</a>
118+
</p>
119+
120+
</div>
121+
122+
</div>
Collapse file
+34Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
2+
:host {
3+
display: block ;
4+
font-size: 18px ;
5+
}
6+
7+
a {
8+
color: red ;
9+
cursor: pointer ;
10+
text-decoration: underline ;
11+
}
12+
13+
input,
14+
button {
15+
font-size: inherit ;
16+
}
17+
18+
.error {
19+
background-color: #ffeeee ;
20+
border: 1px solid #ff0000 ;
21+
border-width: 1px 1px 1px 4px ;
22+
border-radius: 6px 6px 6px 6px ;
23+
color: #ff0000 ;
24+
margin: 16px 0px 16px 0px ;
25+
padding: 15px 25px 15px 25px ;
26+
}
27+
28+
form {
29+
display: flex ;
30+
31+
> * {
32+
margin-right: 10px ;
33+
}
34+
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.