Skip to content

Commit 4a6ab51

Browse files
login fixed
1 parent 407cb61 commit 4a6ab51

File tree

9 files changed

+173
-33
lines changed

9 files changed

+173
-33
lines changed

package-lock.json

Lines changed: 57 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,9 @@
5757
"prettier": "3.4.2",
5858
"supabase": "^2.22.6",
5959
"tailwindcss": "^3.4.4",
60+
"tsx": "^4.19.4",
6061
"typescript": "~5.7.3",
6162
"webpack-bundle-analyzer": "^4.10.2",
6263
"webpack-cli": "^5.1.4"
6364
}
64-
}
65+
}

reset-password.ts

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/**********************************************************************
2+
* reset-password.ts
3+
* -------------------------------------------------
4+
* Resets a Supabase user’s password via the Admin API.
5+
* -------------------------------------------------
6+
* USAGE (bash):
7+
* export SUPABASE_URL="https://aqdbdmepncxxuanlymwr.supabase.co"
8+
* export SERVICE_ROLE_KEY="YOUR_SERVICE_ROLE_KEY_HERE"
9+
* npx ts-node reset-password.ts \
10+
* a3b3cf93-6956-41c7-bec0-1qwqwd42f26 'N3w-Pa$$w0rd!'
11+
*********************************************************************/
12+
13+
import { createClient } from '@supabase/supabase-js';
14+
15+
const [, , userId, newPassword] = process.argv;
16+
17+
if (!userId || !newPassword) {
18+
console.error('Usage: ts-node reset-password.ts <userId> <newPassword>');
19+
process.exit(1);
20+
}
21+
22+
const SUPABASE_URL = process.env.SUPABASE_URL;
23+
const SERVICE_ROLE_KEY = process.env.SERVICE_ROLE_KEY;
24+
25+
if (!SUPABASE_URL || !SERVICE_ROLE_KEY) {
26+
console.error('Set SUPABASE_URL and SERVICE_ROLE_KEY environment variables.');
27+
process.exit(1);
28+
}
29+
30+
(async () => {
31+
const admin = createClient(SUPABASE_URL, SERVICE_ROLE_KEY, {
32+
auth: { autoRefreshToken: false, persistSession: false },
33+
});
34+
35+
const { data, error } = await admin.auth.admin.updateUserById(userId, {
36+
password: newPassword,
37+
});
38+
39+
if (error) {
40+
console.error('❌ Failed to reset password:', error.message);
41+
process.exit(1);
42+
}
43+
44+
console.log(`✅ Password updated for user ${data?.id}`);
45+
})();

src/app/auth/_guards/auth.guard.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,29 +6,42 @@ import { AuthService } from '../auth.service';
66
=======
77
>>>>>>> 34e7e50 (supabase added, firebase removed)
88
import { Roles } from '../../shared/_enums/roles';
9+
<<<<<<< HEAD
910
=======
1011
import { Observable } from 'rxjs';
1112
import { map, take } from 'rxjs/operators';
1213
import { AuthService } from '../auth.service';
1314
>>>>>>> 2ca65a2 (auth guard moved to auth folder)
15+
=======
16+
import { SupabaseService } from '../../services/supabase.service';
17+
>>>>>>> 793fe4a (login fixed)
1418

1519
export const authGuard: CanMatchFn = (): boolean => {
16-
// const authService = inject(AuthService);
20+
const supabaseService = inject(SupabaseService);
1721
const router = inject(Router);
1822
<<<<<<< HEAD
1923

24+
<<<<<<< HEAD
2025
<<<<<<< HEAD
2126
if (authService.user$()?.roles?.includes(Roles.ADMIN)) {
2227
=======
2328
console.log('GUARD', authService.isAdmin$());
2429
if (authService.isAdmin$()) {
2530
>>>>>>> 2ca65a2 (auth guard moved to auth folder)
31+
=======
32+
const session = supabaseService.getSession();
33+
34+
// For now, just check if the user is authenticated
35+
// In a real application, you would check for specific roles in the user's metadata
36+
if (session) {
37+
>>>>>>> 793fe4a (login fixed)
2638
return true;
2739
} else {
2840
router.navigate(['/posts']);
2941
return false;
3042
}
3143
<<<<<<< HEAD
44+
<<<<<<< HEAD
3245
=======
3346

3447
>>>>>>> 2ca65a2 (auth guard moved to auth folder)
@@ -41,4 +54,6 @@ export const authGuard: CanMatchFn = (): boolean => {
4154
// }
4255
return true;
4356
>>>>>>> 34e7e50 (supabase added, firebase removed)
57+
=======
58+
>>>>>>> 793fe4a (login fixed)
4459
};

src/app/auth/login/login.component.ts

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
} from '@angular/core';
88
import { FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms';
99
import { DynamicDialogService } from '../../shared/dynamic-dialog/dynamic-dialog.service';
10+
import { SupabaseService } from '../../services/supabase.service';
1011
import { Credentials } from '../../shared/_models/credentials.interface';
1112
import {
1213
ModalCloseStatusEnum,
@@ -32,27 +33,39 @@ export class LoginCompontent {
3233
loginError: WritableSignal<boolean> = signal(false);
3334

3435
private dynamicDialogService = inject(DynamicDialogService);
36+
private supabaseService = inject(SupabaseService);
3537

3638
onSubmit(): void {
3739
this.isSubmitted = true;
38-
// this.authService.loginWithEmail(this.form.value as Credentials)
39-
// .then(() => {
40-
// this.loginError.set(false);
41-
// const status = {
42-
// closeStatus: ModalCloseStatusEnum.ACCEPTED
43-
// } as ModalStatus;
44-
// this.dynamicDialogService.closeDialog(status);
45-
// })
46-
// .catch(() => {
47-
// this.loginError.set(true);
48-
// });
40+
const credentials = this.form.value as Credentials;
41+
42+
this.supabaseService.signInWithPassword(credentials.email, credentials.password)
43+
.then(({ data, error }) => {
44+
if (error) {
45+
this.loginError.set(true);
46+
return;
47+
}
48+
49+
this.loginError.set(false);
50+
const status = {
51+
closeStatus: ModalCloseStatusEnum.ACCEPTED
52+
} as ModalStatus;
53+
this.dynamicDialogService.closeDialog(status);
54+
})
55+
.catch(() => {
56+
this.loginError.set(true);
57+
});
4958
}
5059

5160
onGoogleLogin() {
52-
// this.authService.loginGoogle();
53-
// const status = {
54-
// closeStatus: ModalCloseStatusEnum.ACCEPTED
55-
// } as ModalStatus;
56-
// this.dynamicDialogService.closeDialog(status);
61+
this.supabaseService.signInWithProvider('google')
62+
.then(({ data, error }) => {
63+
if (!error) {
64+
const status = {
65+
closeStatus: ModalCloseStatusEnum.ACCEPTED
66+
} as ModalStatus;
67+
this.dynamicDialogService.closeDialog(status);
68+
}
69+
});
5770
}
5871
}

src/app/reader/_components/main-page/post/comments/comments.component.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ <h2 class="text-xl font-semibold mb-4">Comments</h2>
77
<p class="text-gray-800 mb-2">{{ comment.content }}</p>
88
<p class="text-sm text-gray-600">- {{ comment.author?.username }}</p>
99
</div>
10-
<button (click)="deleteComment(comment.id!)" class="text-red-500 hover:text-red-700">
10+
<button *hasRole="'Admin'" (click)="deleteComment(comment.id!)" class="text-red-500 hover:text-red-700">
1111
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
1212
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/>
1313
</svg>

src/app/reader/_components/main-page/post/comments/comments.component.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
import { ReaderApiService } from '../../../../_services/reader-api.service';
1010
import { Comment } from '../../../../../types/supabase';
1111
import { CommentsStore } from './comments.store';
12+
import { HasRoleDirective } from '../../../../../shared/_directives/has-role.directive';
1213

1314
@Component({
1415
selector: 'comments',
@@ -17,6 +18,7 @@ import { CommentsStore } from './comments.store';
1718
templateUrl: './comments.component.html',
1819
styleUrl: './comments.component.scss',
1920
changeDetection: ChangeDetectionStrategy.OnPush,
21+
imports: [HasRoleDirective],
2022
})
2123
export class CommentsComponent {
2224
@Input() postId!: string;

src/app/shared/_directives/has-role.directive.ts

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,30 +5,35 @@ import {
55
ViewContainerRef,
66
inject,
77
} from '@angular/core';
8+
import { SupabaseService } from '../../services/supabase.service';
89

910
@Directive({
1011
selector: '[hasRole]',
1112
standalone: true,
1213
})
1314
export class HasRoleDirective {
14-
@Input() set hasRole(roles: string[]) {
15-
this.updateView(roles);
15+
@Input() set hasRole(role: string) {
16+
this.updateView(role);
1617
}
1718

1819
private templateRef = inject(TemplateRef);
1920
private viewContainer = inject(ViewContainerRef);
21+
private supabaseService = inject(SupabaseService);
2022

21-
private updateView(roles: string[]): void {
22-
// const user = this.authService.user$();
23-
// if (user?.roles) {
24-
// const hasRole = user.roles.some(role => roles.includes(role));
25-
// if (hasRole) {
26-
// this.viewContainer.createEmbeddedView(this.templateRef);
27-
// } else {
28-
// this.viewContainer.clear();
29-
// }
30-
// } else {
31-
// this.viewContainer.clear();
32-
// }
23+
private updateView(role: string): void {
24+
const session = this.supabaseService.getSession();
25+
26+
if (session?.user?.app_metadata?.['role']) {
27+
const userRole = session.user.app_metadata?.['role'] as string;
28+
const hasRole = userRole === role;
29+
30+
if (hasRole) {
31+
this.viewContainer.createEmbeddedView(this.templateRef);
32+
} else {
33+
this.viewContainer.clear();
34+
}
35+
} else {
36+
this.viewContainer.clear();
37+
}
3338
}
3439
}

src/app/shared/navbar/navbar.component.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {
1414
import { DynamicDialogService } from '../dynamic-dialog/dynamic-dialog.service';
1515
import { LoginCompontent } from '../../auth/login/login.component';
1616
import { RouterLink } from '@angular/router';
17+
import { SupabaseService } from '../../services/supabase.service';
1718

1819
@Component({
1920
selector: 'blog-navbar',
@@ -33,6 +34,7 @@ export class NavbarComponent implements AfterViewInit {
3334

3435
private dynamicDialogService = inject(DynamicDialogService);
3536
private viewContainerRef = inject(ViewContainerRef);
37+
private supabaseService = inject(SupabaseService);
3638

3739
constructor() {
3840
afterNextRender(() => {

0 commit comments

Comments
 (0)