[A] basic signup, login, logout

This commit is contained in:
Jan 2020-10-26 23:32:51 +01:00
parent 70ea10d715
commit a5531c5cdf
9 changed files with 174 additions and 45 deletions

48
package-lock.json generated
View file

@ -3279,7 +3279,6 @@
"resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz", "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz",
"integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=", "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=",
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"hoek": "2.x.x" "hoek": "2.x.x"
} }
@ -3474,8 +3473,7 @@
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/buffer-more-ints/-/buffer-more-ints-1.0.0.tgz", "resolved": "https://registry.npmjs.org/buffer-more-ints/-/buffer-more-ints-1.0.0.tgz",
"integrity": "sha512-EMetuGFz5SLsT0QTnXzINh4Ksr+oo4i+UGTXEshiGCQWnsgSs7ZhJ8fzlwQ+OzEMs0MpDAMr1hxnblp5a4vcHg==", "integrity": "sha512-EMetuGFz5SLsT0QTnXzINh4Ksr+oo4i+UGTXEshiGCQWnsgSs7ZhJ8fzlwQ+OzEMs0MpDAMr1hxnblp5a4vcHg==",
"dev": true, "dev": true
"optional": true
}, },
"buffer-xor": { "buffer-xor": {
"version": "1.0.3", "version": "1.0.3",
@ -6784,8 +6782,7 @@
"version": "2.16.3", "version": "2.16.3",
"resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz", "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz",
"integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=", "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=",
"dev": true, "dev": true
"optional": true
}, },
"homedir-polyfill": { "homedir-polyfill": {
"version": "1.0.3", "version": "1.0.3",
@ -7065,7 +7062,6 @@
"resolved": "https://registry.npmjs.org/httpntlm/-/httpntlm-1.6.1.tgz", "resolved": "https://registry.npmjs.org/httpntlm/-/httpntlm-1.6.1.tgz",
"integrity": "sha1-rQFScUOi6Hc8+uapb1hla7UqNLI=", "integrity": "sha1-rQFScUOi6Hc8+uapb1hla7UqNLI=",
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"httpreq": ">=0.4.22", "httpreq": ">=0.4.22",
"underscore": "~1.7.0" "underscore": "~1.7.0"
@ -7075,8 +7071,7 @@
"version": "0.4.24", "version": "0.4.24",
"resolved": "https://registry.npmjs.org/httpreq/-/httpreq-0.4.24.tgz", "resolved": "https://registry.npmjs.org/httpreq/-/httpreq-0.4.24.tgz",
"integrity": "sha1-QzX/2CzZaWaKOUZckprGHWOTYn8=", "integrity": "sha1-QzX/2CzZaWaKOUZckprGHWOTYn8=",
"dev": true, "dev": true
"optional": true
}, },
"https-browserify": { "https-browserify": {
"version": "1.0.0", "version": "1.0.0",
@ -7616,8 +7611,7 @@
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz",
"integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=", "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=",
"dev": true, "dev": true
"optional": true
}, },
"is-regex": { "is-regex": {
"version": "1.1.1", "version": "1.1.1",
@ -8595,15 +8589,13 @@
"version": "0.1.0", "version": "0.1.0",
"resolved": "https://registry.npmjs.org/libbase64/-/libbase64-0.1.0.tgz", "resolved": "https://registry.npmjs.org/libbase64/-/libbase64-0.1.0.tgz",
"integrity": "sha1-YjUag5VjrF/1vSbxL2Dpgwu3UeY=", "integrity": "sha1-YjUag5VjrF/1vSbxL2Dpgwu3UeY=",
"dev": true, "dev": true
"optional": true
}, },
"libmime": { "libmime": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/libmime/-/libmime-3.0.0.tgz", "resolved": "https://registry.npmjs.org/libmime/-/libmime-3.0.0.tgz",
"integrity": "sha1-UaGp50SOy9Ms2lRCFnW7IbwJPaY=", "integrity": "sha1-UaGp50SOy9Ms2lRCFnW7IbwJPaY=",
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"iconv-lite": "0.4.15", "iconv-lite": "0.4.15",
"libbase64": "0.1.0", "libbase64": "0.1.0",
@ -8614,8 +8606,7 @@
"version": "0.4.15", "version": "0.4.15",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.15.tgz", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.15.tgz",
"integrity": "sha1-/iZaIYrGpXz+hUkn6dBMGYJe3es=", "integrity": "sha1-/iZaIYrGpXz+hUkn6dBMGYJe3es=",
"dev": true, "dev": true
"optional": true
} }
} }
}, },
@ -8623,8 +8614,7 @@
"version": "1.1.0", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/libqp/-/libqp-1.1.0.tgz", "resolved": "https://registry.npmjs.org/libqp/-/libqp-1.1.0.tgz",
"integrity": "sha1-9ebgatdLeU+1tbZpiL9yjvHe2+g=", "integrity": "sha1-9ebgatdLeU+1tbZpiL9yjvHe2+g=",
"dev": true, "dev": true
"optional": true
}, },
"license-webpack-plugin": { "license-webpack-plugin": {
"version": "2.2.0", "version": "2.2.0",
@ -9723,15 +9713,13 @@
"version": "1.6.0", "version": "1.6.0",
"resolved": "https://registry.npmjs.org/nodemailer-fetch/-/nodemailer-fetch-1.6.0.tgz", "resolved": "https://registry.npmjs.org/nodemailer-fetch/-/nodemailer-fetch-1.6.0.tgz",
"integrity": "sha1-ecSQihwPXzdbc/6IjamCj23JY6Q=", "integrity": "sha1-ecSQihwPXzdbc/6IjamCj23JY6Q=",
"dev": true, "dev": true
"optional": true
}, },
"nodemailer-shared": { "nodemailer-shared": {
"version": "1.1.0", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/nodemailer-shared/-/nodemailer-shared-1.1.0.tgz", "resolved": "https://registry.npmjs.org/nodemailer-shared/-/nodemailer-shared-1.1.0.tgz",
"integrity": "sha1-z1mU4v0mjQD1zw+nZ6CBae2wfsA=", "integrity": "sha1-z1mU4v0mjQD1zw+nZ6CBae2wfsA=",
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"nodemailer-fetch": "1.6.0" "nodemailer-fetch": "1.6.0"
} }
@ -9764,8 +9752,7 @@
"version": "0.1.10", "version": "0.1.10",
"resolved": "https://registry.npmjs.org/nodemailer-wellknown/-/nodemailer-wellknown-0.1.10.tgz", "resolved": "https://registry.npmjs.org/nodemailer-wellknown/-/nodemailer-wellknown-0.1.10.tgz",
"integrity": "sha1-WG24EB2zDLRDjrVGc3pBqtDPE9U=", "integrity": "sha1-WG24EB2zDLRDjrVGc3pBqtDPE9U=",
"dev": true, "dev": true
"optional": true
}, },
"normalize-package-data": { "normalize-package-data": {
"version": "2.5.0", "version": "2.5.0",
@ -11578,8 +11565,7 @@
"version": "1.1.2", "version": "1.1.2",
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
"integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=",
"dev": true, "dev": true
"optional": true
}, },
"prepend-http": { "prepend-http": {
"version": "1.0.4", "version": "1.0.4",
@ -13458,7 +13444,6 @@
"resolved": "https://registry.npmjs.org/smtp-connection/-/smtp-connection-2.12.0.tgz", "resolved": "https://registry.npmjs.org/smtp-connection/-/smtp-connection-2.12.0.tgz",
"integrity": "sha1-1275EnyyPCJZ7bHoNJwujV4tdME=", "integrity": "sha1-1275EnyyPCJZ7bHoNJwujV4tdME=",
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"httpntlm": "1.6.1", "httpntlm": "1.6.1",
"nodemailer-shared": "1.1.0" "nodemailer-shared": "1.1.0"
@ -14866,7 +14851,6 @@
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
"integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=",
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"prelude-ls": "~1.1.2" "prelude-ls": "~1.1.2"
} }
@ -14944,8 +14928,7 @@
"version": "1.7.0", "version": "1.7.0",
"resolved": "https://registry.npmjs.org/underscore/-/underscore-1.7.0.tgz", "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.7.0.tgz",
"integrity": "sha1-a7rwh3UA02vjTsqlhODbn+8DUgk=", "integrity": "sha1-a7rwh3UA02vjTsqlhODbn+8DUgk=",
"dev": true, "dev": true
"optional": true
}, },
"unicode-canonical-property-names-ecmascript": { "unicode-canonical-property-names-ecmascript": {
"version": "1.0.4", "version": "1.0.4",
@ -15484,15 +15467,13 @@
"version": "0.3.2", "version": "0.3.2",
"resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
"integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
"dev": true, "dev": true
"optional": true
}, },
"braces": { "braces": {
"version": "2.3.2", "version": "2.3.2",
"resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
"integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"arr-flatten": "^1.1.0", "arr-flatten": "^1.1.0",
"array-unique": "^0.3.2", "array-unique": "^0.3.2",
@ -15511,7 +15492,6 @@
"resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
"integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"is-extendable": "^0.1.0" "is-extendable": "^0.1.0"
} }
@ -15544,7 +15524,6 @@
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
"integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"extend-shallow": "^2.0.1", "extend-shallow": "^2.0.1",
"is-number": "^3.0.0", "is-number": "^3.0.0",
@ -15557,7 +15536,6 @@
"resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
"integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"is-extendable": "^0.1.0" "is-extendable": "^0.1.0"
} }
@ -15592,7 +15570,6 @@
"resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
"integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"kind-of": "^3.0.2" "kind-of": "^3.0.2"
}, },
@ -15602,7 +15579,6 @@
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
"integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"is-buffer": "^1.1.5" "is-buffer": "^1.1.5"
} }

View file

@ -1,5 +1,6 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { createClient, SupabaseClient } from '@supabase/supabase-js' import { createClient, SupabaseAuthUser, SupabaseClient } from '@supabase/supabase-js'
import { BehaviorSubject } from 'rxjs';
import { environment } from '../../../environments/environment' import { environment } from '../../../environments/environment'
@ -8,10 +9,50 @@ import { environment } from '../../../environments/environment'
}) })
export class SupaService { export class SupaService {
client: SupabaseClient; client: SupabaseClient;
user: BehaviorSubject<SupabaseAuthUser> = new BehaviorSubject(null);
constructor() { constructor() {
// Create a single supabase client for interacting with your database // Create a single supabase client for interacting with your database
this.client = createClient(environment.supa_url, environment.supa_key); this.client = createClient(environment.supa_url, environment.supa_key);
console.log('supa', this.client) this.getUser();
}
async getUser() {
const user = await this.client.auth.user();
console.log('user', user);
this.user.next(user);
}
async login(email: string, password: string): Promise<SupabaseAuthUser> {
try {
const res = await this.client.auth.login(
email,
password
);
this.user.next(res.body.user);
return res.body.user;
} catch (e) {
console.error('Login', e);
} }
} }
async logout(): Promise<any> {
return this.client.auth.logout()
.then(() => this.user.next(null))
.catch((e) =>console.error('Logout', e));
}
async signup(email: string, password: string): Promise<SupabaseAuthUser> {
try {
const res = await this.client.auth.signup(
email,
password
);
this.user.next(res.body.user);
return res.body.user;
} catch (e) {
console.error('Signup', e);
}
}
}

View file

@ -1,5 +1,6 @@
<nav class="navbar navbar-light bg-light"> <nav class="navbar navbar-light bg-light">
<a class="navbar-brand" href="#" style="margin: 0 auto;">ASYNC HUDDLE</a> <a class="navbar-brand" href="#" style="margin: 0 auto;">ASYNC HUDDLE</a>
<span *ngIf="supa.user | async" (click)="logout()">Logout</span>
</nav> </nav>
<div class="container"> <div class="container">
<router-outlet></router-outlet> <router-outlet></router-outlet>

View file

@ -1,9 +1,37 @@
import { Component } from "@angular/core"; import { Component, OnInit } from "@angular/core";
import { Router } from '@angular/router';
import { SupabaseAuthUser } from '@supabase/supabase-js';
import { SupaService } from './api/supabase/supa.service';
@Component({ @Component({
selector: "app-root", selector: "app-root",
templateUrl: "./app.component.html", templateUrl: "./app.component.html",
styleUrls: ["./app.component.scss"] styleUrls: ["./app.component.scss"]
}) })
export class AppComponent { export class AppComponent implements OnInit {
user: SupabaseAuthUser;
constructor(
public supa: SupaService,
private router: Router,
) { }
async ngOnInit() {
try {
this.user = await this.supa.client.auth.user();
} catch (e) {
console.log(e.msg);
this.router.navigate(['/login']);
}
}
async logout() {
try {
await this.supa.logout();
this.router.navigate(['/login']);
} catch (e) {
console.error(e);
}
}
} }

View file

@ -3,6 +3,7 @@ import { NgModule } from "@angular/core";
import { NgbModalModule } from "@ng-bootstrap/ng-bootstrap"; import { NgbModalModule } from "@ng-bootstrap/ng-bootstrap";
import { AppRoutingModule } from './app-routing.module'; import { AppRoutingModule } from './app-routing.module';
import { FormsModule } from '@angular/forms';
import { SupaService } from './api/supabase/supa.service'; import { SupaService } from './api/supabase/supa.service';
import { AuthGuard } from './authguard.service'; import { AuthGuard } from './authguard.service';
@ -24,7 +25,9 @@ import { HuddleComponent } from './huddle/huddle.component';
imports: [ imports: [
BrowserModule, BrowserModule,
NgbModalModule, NgbModalModule,
AppRoutingModule], AppRoutingModule,
FormsModule,
],
providers: [ providers: [
SupaService, SupaService,
AuthGuard, AuthGuard,

View file

@ -1 +1,22 @@
<p>login works!</p> <div class="row mt-3 justify-content-md-center">
<div class="form-group col-12 col-sm-4">
<label for="email">Email</label>
<input #email class="form-control" type="email">
</div>
</div>
<div class="row justify-content-md-center">
<div class="form-group col-12 col-sm-4">
<label for="password">Password</label>
<input #password class="form-control" type="password">
</div>
</div>
<div class="row justify-content-md-center">
<div class="col-12 col-sm-4">
<button class="btn btn-primary text-uppercase" type="button" (click)="login(email.value, password.value)">
Log in
</button> or
<a class="btn btn-secondary text-uppercase" [routerLink]="'/signup'">
signup
</a>
</div>
</div>

View file

@ -1,4 +1,6 @@
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { SupaService } from '../api/supabase/supa.service';
@Component({ @Component({
selector: 'app-login', selector: 'app-login',
@ -7,9 +9,21 @@ import { Component, OnInit } from '@angular/core';
}) })
export class LoginComponent implements OnInit { export class LoginComponent implements OnInit {
constructor() { } constructor(
private router: Router,
private supa: SupaService,
) { }
ngOnInit(): void { ngOnInit(): void {
} }
async login(email: string, password: string) {
try {
await this.supa.login(email, password);
this.router.navigateByUrl('/');
} catch (e) {
console.error('login component', e);
}
}
} }

View file

@ -1 +1,25 @@
<p>signup works!</p> <div class="row mt-3 justify-content-md-center">
<div class="form-group col-12 col-sm-4">
<label for="email">Email</label>
<input [(ngModel)]="email" class="form-control" type="email">
</div>
</div>
<div class="row justify-content-md-center">
<div class="form-group col-12 col-sm-4">
<label for="password">Password</label>
<input [(ngModel)]="password" class="form-control" type="password">
</div>
</div>
<div class="row justify-content-md-center">
<div class="form-group col-12 col-sm-4">
<label for="password">Repeat password</label>
<input [(ngModel)]="repeat" class="form-control" type="password">
</div>
</div>
<div class="row justify-content-md-center">
<div class="col-12 col-sm-4">
<button type="button" class="btn btn-secondary text-uppercase" (click)="signup(email, password, repeat)">
signup
</button>
</div>
</div>

View file

@ -1,4 +1,6 @@
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { SupaService } from '../api/supabase/supa.service';
@Component({ @Component({
selector: 'app-signup', selector: 'app-signup',
@ -6,10 +8,29 @@ import { Component, OnInit } from '@angular/core';
styleUrls: ['./signup.component.scss'] styleUrls: ['./signup.component.scss']
}) })
export class SignupComponent implements OnInit { export class SignupComponent implements OnInit {
email: string = '';
password: string = '';
repeat: string = '';
constructor() { } constructor(
private supa: SupaService,
private router: Router,
) { }
ngOnInit(): void { ngOnInit(): void {
} }
async signup(email: string, password: string, repeat: string) {
console.log(email, password, repeat);
if (!email || (email.length <= 0) || !password || (password.length <= 0) || !repeat || (repeat.length <= 0) || (password !== repeat)) {
return;
}
try {
await this.supa.signup(email, password);
this.router.navigate(['/']);
} catch (e) {
console.error('signup component', e);
}
}
} }