@nytejs/auth 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +13 -0
- package/README.md +48 -0
- package/dist/client.d.ts +24 -0
- package/dist/client.js +146 -0
- package/dist/components.d.ts +19 -0
- package/dist/components.js +73 -0
- package/dist/core.d.ts +55 -0
- package/dist/core.js +189 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +45 -0
- package/dist/jwt.d.ts +41 -0
- package/dist/jwt.js +185 -0
- package/dist/providers/credentials.d.ts +60 -0
- package/dist/providers/credentials.js +97 -0
- package/dist/providers/discord.d.ts +63 -0
- package/dist/providers/discord.js +190 -0
- package/dist/providers/google.d.ts +63 -0
- package/dist/providers/google.js +186 -0
- package/dist/providers/index.d.ts +2 -0
- package/dist/providers/index.js +35 -0
- package/dist/providers.d.ts +3 -0
- package/dist/providers.js +26 -0
- package/dist/react/index.d.ts +6 -0
- package/dist/react/index.js +47 -0
- package/dist/react.d.ts +22 -0
- package/dist/react.js +199 -0
- package/dist/routes.d.ts +16 -0
- package/dist/routes.js +152 -0
- package/dist/types.d.ts +76 -0
- package/dist/types.js +18 -0
- package/package.json +51 -0
- package/src/client.ts +171 -0
- package/src/components.tsx +84 -0
- package/src/core.ts +215 -0
- package/src/index.ts +25 -0
- package/src/jwt.ts +210 -0
- package/src/providers/credentials.ts +138 -0
- package/src/providers/discord.ts +239 -0
- package/src/providers/google.ts +234 -0
- package/src/providers/index.ts +20 -0
- package/src/providers.ts +20 -0
- package/src/react/index.ts +25 -0
- package/src/react.tsx +234 -0
- package/src/routes.ts +182 -0
- package/src/types.ts +108 -0
package/dist/routes.js
ADDED
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createAuthRoutes = createAuthRoutes;
|
|
4
|
+
/*
|
|
5
|
+
* This file is part of the Nyte.js Project.
|
|
6
|
+
* Copyright (c) 2026 itsmuzin
|
|
7
|
+
*
|
|
8
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
9
|
+
* you may not use this file except in compliance with the License.
|
|
10
|
+
* You may obtain a copy of the License at
|
|
11
|
+
*
|
|
12
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
13
|
+
*
|
|
14
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
15
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
16
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
17
|
+
* See the License for the specific language governing permissions and
|
|
18
|
+
* limitations under the License.
|
|
19
|
+
*/
|
|
20
|
+
const nyte_1 = require("nyte");
|
|
21
|
+
const core_1 = require("./core");
|
|
22
|
+
/**
|
|
23
|
+
* Cria o handler catch-all para /api/auth/[...value]
|
|
24
|
+
*/
|
|
25
|
+
function createAuthRoutes(config) {
|
|
26
|
+
const auth = new core_1.HWebAuth(config);
|
|
27
|
+
/**
|
|
28
|
+
* Handler principal que gerencia todas as rotas de auth
|
|
29
|
+
* Uso: /api/auth/[...value].ts
|
|
30
|
+
*/
|
|
31
|
+
return {
|
|
32
|
+
pattern: '/api/auth/[...value]',
|
|
33
|
+
async GET(req, params) {
|
|
34
|
+
const path = params["value"];
|
|
35
|
+
const route = Array.isArray(path) ? path.join('/') : path || '';
|
|
36
|
+
// Verifica rotas adicionais dos providers primeiro
|
|
37
|
+
const additionalRoutes = auth.getAllAdditionalRoutes();
|
|
38
|
+
for (const { provider, route: additionalRoute } of additionalRoutes) {
|
|
39
|
+
if (additionalRoute.method === 'GET' && additionalRoute.path.includes(route)) {
|
|
40
|
+
try {
|
|
41
|
+
return await additionalRoute.handler(req, params);
|
|
42
|
+
}
|
|
43
|
+
catch (error) {
|
|
44
|
+
console.error(`[${provider} Provider] Error in additional route:`, error);
|
|
45
|
+
return nyte_1.NyteResponse.json({ error: 'Provider route error' }, { status: 500 });
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
// Rotas padrão do sistema
|
|
50
|
+
switch (route) {
|
|
51
|
+
case 'session':
|
|
52
|
+
return await handleSession(req, auth);
|
|
53
|
+
case 'csrf':
|
|
54
|
+
return await handleCsrf(req);
|
|
55
|
+
case 'providers':
|
|
56
|
+
return await handleProviders(auth);
|
|
57
|
+
default:
|
|
58
|
+
return nyte_1.NyteResponse.json({ error: 'Route not found' }, { status: 404 });
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
async POST(req, params) {
|
|
62
|
+
const path = params["value"];
|
|
63
|
+
const route = Array.isArray(path) ? path.join('/') : path || '';
|
|
64
|
+
// Verifica rotas adicionais dos providers primeiro
|
|
65
|
+
const additionalRoutes = auth.getAllAdditionalRoutes();
|
|
66
|
+
for (const { provider, route: additionalRoute } of additionalRoutes) {
|
|
67
|
+
if (additionalRoute.method === 'POST' && additionalRoute.path.includes(route)) {
|
|
68
|
+
try {
|
|
69
|
+
return await additionalRoute.handler(req, params);
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
console.error(`[${provider} Provider] Error in additional route:`, error);
|
|
73
|
+
return nyte_1.NyteResponse.json({ error: 'Provider route error' }, { status: 500 });
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
// Rotas padrão do sistema
|
|
78
|
+
switch (route) {
|
|
79
|
+
case 'signin':
|
|
80
|
+
return await handleSignIn(req, auth);
|
|
81
|
+
case 'signout':
|
|
82
|
+
return await handleSignOut(req, auth);
|
|
83
|
+
default:
|
|
84
|
+
return nyte_1.NyteResponse.json({ error: 'Route not found' }, { status: 404 });
|
|
85
|
+
}
|
|
86
|
+
},
|
|
87
|
+
// Instância do auth para uso manual
|
|
88
|
+
auth
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Handler para GET /api/auth/session
|
|
93
|
+
*/
|
|
94
|
+
async function handleSession(req, auth) {
|
|
95
|
+
const session = await auth.getSession(req);
|
|
96
|
+
if (!session) {
|
|
97
|
+
return nyte_1.NyteResponse.json({ session: null });
|
|
98
|
+
}
|
|
99
|
+
return nyte_1.NyteResponse.json({ session });
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Handler para GET /api/auth/csrf
|
|
103
|
+
*/
|
|
104
|
+
async function handleCsrf(req) {
|
|
105
|
+
// Token CSRF simples para proteção
|
|
106
|
+
const csrfToken = Math.random().toString(36).substring(2, 15) +
|
|
107
|
+
Math.random().toString(36).substring(2, 15);
|
|
108
|
+
return nyte_1.NyteResponse.json({ csrfToken });
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Handler para GET /api/auth/providers
|
|
112
|
+
*/
|
|
113
|
+
async function handleProviders(auth) {
|
|
114
|
+
const providers = auth.getProviders();
|
|
115
|
+
return nyte_1.NyteResponse.json({ providers });
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Handler para POST /api/auth/signin
|
|
119
|
+
*/
|
|
120
|
+
async function handleSignIn(req, auth) {
|
|
121
|
+
try {
|
|
122
|
+
const { provider = 'credentials', ...credentials } = await req.json();
|
|
123
|
+
const result = await auth.signIn(provider, credentials);
|
|
124
|
+
if (!result) {
|
|
125
|
+
return nyte_1.NyteResponse.json({ error: 'Invalid credentials' }, { status: 401 });
|
|
126
|
+
}
|
|
127
|
+
// Se tem redirectUrl, é OAuth - retorna URL para redirecionamento
|
|
128
|
+
if ('redirectUrl' in result) {
|
|
129
|
+
return nyte_1.NyteResponse.json({
|
|
130
|
+
success: true,
|
|
131
|
+
redirectUrl: result.redirectUrl,
|
|
132
|
+
type: 'oauth'
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
// Se tem session, é credentials - retorna sessão
|
|
136
|
+
return auth.createAuthResponse(result.token, {
|
|
137
|
+
success: true,
|
|
138
|
+
user: result.session.user,
|
|
139
|
+
type: 'session'
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
catch (error) {
|
|
143
|
+
console.error('[hweb-auth] Error on handleSignIn:', error);
|
|
144
|
+
return nyte_1.NyteResponse.json({ error: 'Authentication failed' }, { status: 500 });
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Handler para POST /api/auth/signout
|
|
149
|
+
*/
|
|
150
|
+
async function handleSignOut(req, auth) {
|
|
151
|
+
return await auth.signOut(req);
|
|
152
|
+
}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
export type User = Record<string, any>;
|
|
2
|
+
export interface Session {
|
|
3
|
+
user: User;
|
|
4
|
+
expires: string;
|
|
5
|
+
accessToken?: string;
|
|
6
|
+
}
|
|
7
|
+
export interface SignInOptions {
|
|
8
|
+
redirect?: boolean;
|
|
9
|
+
callbackUrl?: string;
|
|
10
|
+
[key: string]: any;
|
|
11
|
+
}
|
|
12
|
+
export interface SignInResult {
|
|
13
|
+
error?: string;
|
|
14
|
+
status?: number;
|
|
15
|
+
ok?: boolean;
|
|
16
|
+
url?: string;
|
|
17
|
+
}
|
|
18
|
+
export interface SessionContextType {
|
|
19
|
+
data: Session | null;
|
|
20
|
+
status: 'loading' | 'authenticated' | 'unauthenticated';
|
|
21
|
+
signIn: (provider?: string, options?: SignInOptions) => Promise<SignInResult | undefined>;
|
|
22
|
+
signOut: (options?: {
|
|
23
|
+
callbackUrl?: string;
|
|
24
|
+
}) => Promise<void>;
|
|
25
|
+
update: () => Promise<Session | null>;
|
|
26
|
+
}
|
|
27
|
+
export interface AuthRoute {
|
|
28
|
+
method: 'GET' | 'POST' | 'PUT' | 'DELETE';
|
|
29
|
+
path: string;
|
|
30
|
+
handler: (req: any, params: any) => Promise<any>;
|
|
31
|
+
}
|
|
32
|
+
export interface AuthProviderClass {
|
|
33
|
+
id: string;
|
|
34
|
+
name: string;
|
|
35
|
+
type: string;
|
|
36
|
+
handleOauth?(credentials: Record<string, string>): Promise<string> | string;
|
|
37
|
+
handleSignIn(credentials: Record<string, string>): Promise<User | string | null>;
|
|
38
|
+
handleSignOut?(): Promise<void>;
|
|
39
|
+
additionalRoutes?: AuthRoute[];
|
|
40
|
+
getConfig?(): any;
|
|
41
|
+
}
|
|
42
|
+
export interface AuthConfig {
|
|
43
|
+
providers: AuthProviderClass[];
|
|
44
|
+
pages?: {
|
|
45
|
+
signIn?: string;
|
|
46
|
+
signOut?: string;
|
|
47
|
+
error?: string;
|
|
48
|
+
};
|
|
49
|
+
callbacks?: {
|
|
50
|
+
signIn?: (user: User, account: any, profile: any) => boolean | Promise<boolean>;
|
|
51
|
+
session?: ({ session, user, provider }: {
|
|
52
|
+
session: Session;
|
|
53
|
+
user: User;
|
|
54
|
+
provider: string;
|
|
55
|
+
}) => Session | Promise<Session>;
|
|
56
|
+
jwt?: (token: any, user: User, account: any, profile: any) => any | Promise<any>;
|
|
57
|
+
};
|
|
58
|
+
session?: {
|
|
59
|
+
strategy?: 'jwt' | 'database';
|
|
60
|
+
maxAge?: number;
|
|
61
|
+
updateAge?: number;
|
|
62
|
+
};
|
|
63
|
+
secret?: string;
|
|
64
|
+
debug?: boolean;
|
|
65
|
+
secureCookies?: boolean;
|
|
66
|
+
}
|
|
67
|
+
export interface CredentialsConfig {
|
|
68
|
+
id?: string;
|
|
69
|
+
name?: string;
|
|
70
|
+
credentials: Record<string, {
|
|
71
|
+
label: string;
|
|
72
|
+
type: string;
|
|
73
|
+
placeholder?: string;
|
|
74
|
+
}>;
|
|
75
|
+
authorize: (credentials: Record<string, string>) => Promise<User | null> | User | null;
|
|
76
|
+
}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* This file is part of the Nyte.js Project.
|
|
4
|
+
* Copyright (c) 2026 itsmuzin
|
|
5
|
+
*
|
|
6
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
|
+
* you may not use this file except in compliance with the License.
|
|
8
|
+
* You may obtain a copy of the License at
|
|
9
|
+
*
|
|
10
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
*
|
|
12
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
13
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
14
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
15
|
+
* See the License for the specific language governing permissions and
|
|
16
|
+
* limitations under the License.
|
|
17
|
+
*/
|
|
18
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@nytejs/auth",
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"description": "Authentication package for Nyte.js framework",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"private": false,
|
|
8
|
+
"author": "itsmuzin",
|
|
9
|
+
"license": "Apache-2.0",
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"import": "./dist/index.js",
|
|
14
|
+
"require": "./dist/index.js"
|
|
15
|
+
},
|
|
16
|
+
"./react": {
|
|
17
|
+
"types": "./dist/react/index.d.ts",
|
|
18
|
+
"import": "./dist/react/index.js",
|
|
19
|
+
"require": "./dist/react/index.js"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"keywords": [
|
|
23
|
+
"hightjs",
|
|
24
|
+
"nytejs",
|
|
25
|
+
"nyte",
|
|
26
|
+
"auth",
|
|
27
|
+
"authentication",
|
|
28
|
+
"framework"
|
|
29
|
+
],
|
|
30
|
+
"files": [
|
|
31
|
+
"dist",
|
|
32
|
+
"README.md",
|
|
33
|
+
"src"
|
|
34
|
+
],
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"@types/node": "^20.11.24",
|
|
37
|
+
"rimraf": "^5.0.0",
|
|
38
|
+
"typescript": "^5.9.3"
|
|
39
|
+
},
|
|
40
|
+
"dependencies": {
|
|
41
|
+
"@types/react": "^19.2.2",
|
|
42
|
+
"react": "^19.2.0",
|
|
43
|
+
"nyte": "1.0.1"
|
|
44
|
+
},
|
|
45
|
+
"scripts": {
|
|
46
|
+
"build": "tsc",
|
|
47
|
+
"build:watch": "tsc --watch",
|
|
48
|
+
"clean": "rimraf dist",
|
|
49
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
50
|
+
}
|
|
51
|
+
}
|
package/src/client.ts
ADDED
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* This file is part of the Nyte.js Project.
|
|
3
|
+
* Copyright (c) 2026 itsmuzin
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
import type { SignInOptions, SignInResult, Session } from './types';
|
|
18
|
+
// Configuração global do client
|
|
19
|
+
let basePath = '/api/auth';
|
|
20
|
+
|
|
21
|
+
export function setBasePath(path: string) {
|
|
22
|
+
basePath = path;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Função para obter a sessão atual (similar ao NextAuth getSession)
|
|
27
|
+
*/
|
|
28
|
+
export async function getSession(): Promise<Session | null> {
|
|
29
|
+
try {
|
|
30
|
+
const response = await fetch(`${basePath}/session`, {
|
|
31
|
+
credentials: 'include'
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
if (!response.ok) {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const data = await response.json();
|
|
39
|
+
return data.session || null;
|
|
40
|
+
} catch (error) {
|
|
41
|
+
console.error('[hweb-auth] Error fetching session:', error);
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Função para obter token CSRF
|
|
48
|
+
*/
|
|
49
|
+
export async function getCsrfToken(): Promise<string | null> {
|
|
50
|
+
try {
|
|
51
|
+
const response = await fetch(`${basePath}/csrf`, {
|
|
52
|
+
credentials: 'include'
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
if (!response.ok) {
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const data = await response.json();
|
|
60
|
+
return data.csrfToken || null;
|
|
61
|
+
} catch (error) {
|
|
62
|
+
console.error('[hweb-auth] Error fetching CSRF token:', error);
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Função para obter providers disponíveis
|
|
69
|
+
*/
|
|
70
|
+
export async function getProviders(): Promise<any[] | null> {
|
|
71
|
+
try {
|
|
72
|
+
const response = await fetch(`${basePath}/providers`, {
|
|
73
|
+
credentials: 'include'
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
if (!response.ok) {
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const data = await response.json();
|
|
81
|
+
return data.providers || [];
|
|
82
|
+
} catch (error) {
|
|
83
|
+
console.error('[hweb-auth] Error searching for providers:', error);
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Função para fazer login (similar ao NextAuth signIn)
|
|
90
|
+
*/
|
|
91
|
+
export async function signIn(
|
|
92
|
+
provider: string = 'credentials',
|
|
93
|
+
options: SignInOptions = {}
|
|
94
|
+
): Promise<SignInResult | undefined> {
|
|
95
|
+
try {
|
|
96
|
+
const { redirect = true, callbackUrl, ...credentials } = options;
|
|
97
|
+
|
|
98
|
+
const response = await fetch(`${basePath}/signin`, {
|
|
99
|
+
method: 'POST',
|
|
100
|
+
headers: {
|
|
101
|
+
'Content-Type': 'application/json',
|
|
102
|
+
},
|
|
103
|
+
credentials: 'include',
|
|
104
|
+
body: JSON.stringify({
|
|
105
|
+
provider,
|
|
106
|
+
...credentials
|
|
107
|
+
})
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
const data = await response.json();
|
|
111
|
+
|
|
112
|
+
if (response.ok && data.success) {
|
|
113
|
+
// Se é OAuth, redireciona para URL fornecida
|
|
114
|
+
if (data.type === 'oauth' && data.redirectUrl) {
|
|
115
|
+
if (redirect && typeof window !== 'undefined') {
|
|
116
|
+
window.location.href = data.redirectUrl;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
return {
|
|
120
|
+
ok: true,
|
|
121
|
+
status: 200,
|
|
122
|
+
url: data.redirectUrl
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// Se é sessão (credentials), redireciona para callbackUrl
|
|
127
|
+
if (data.type === 'session') {
|
|
128
|
+
if (redirect && typeof window !== 'undefined') {
|
|
129
|
+
window.location.href = callbackUrl || '/';
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
return {
|
|
133
|
+
ok: true,
|
|
134
|
+
status: 200,
|
|
135
|
+
url: callbackUrl || '/'
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
} else {
|
|
139
|
+
return {
|
|
140
|
+
error: data.error || 'Authentication failed',
|
|
141
|
+
status: response.status,
|
|
142
|
+
ok: false
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
} catch (error) {
|
|
146
|
+
console.error('[hweb-auth] Error on signIn:', error);
|
|
147
|
+
return {
|
|
148
|
+
error: 'Network error',
|
|
149
|
+
status: 500,
|
|
150
|
+
ok: false
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Função para fazer logout (similar ao NextAuth signOut)
|
|
157
|
+
*/
|
|
158
|
+
export async function signOut(options: { callbackUrl?: string } = {}): Promise<void> {
|
|
159
|
+
try {
|
|
160
|
+
await fetch(`${basePath}/signout`, {
|
|
161
|
+
method: 'POST',
|
|
162
|
+
credentials: 'include'
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
if (typeof window !== 'undefined') {
|
|
166
|
+
window.location.href = options.callbackUrl || '/';
|
|
167
|
+
}
|
|
168
|
+
} catch (error) {
|
|
169
|
+
console.error('[hweb-auth] Error on signOut:', error);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* This file is part of the Nyte.js Project.
|
|
3
|
+
* Copyright (c) 2026 itsmuzin
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
import React, { ReactNode } from 'react';
|
|
18
|
+
import { useAuth } from './react';
|
|
19
|
+
import { router } from 'nyte/react';
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
interface GuardProps {
|
|
23
|
+
children: ReactNode;
|
|
24
|
+
fallback?: ReactNode;
|
|
25
|
+
redirectTo?: string;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Guard simples que só renderiza children se estiver autenticado
|
|
30
|
+
*/
|
|
31
|
+
export function AuthGuard({ children, fallback, redirectTo }: GuardProps) {
|
|
32
|
+
const { isAuthenticated, isLoading } = useAuth();
|
|
33
|
+
|
|
34
|
+
if(redirectTo && !isLoading && !isAuthenticated) {
|
|
35
|
+
router.push(redirectTo);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (isLoading) {
|
|
39
|
+
return fallback || <div></div>;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (!isAuthenticated) {
|
|
43
|
+
return fallback || null;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return <>{children}</>;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Componente para mostrar conteúdo apenas para usuários não autenticados
|
|
51
|
+
*/
|
|
52
|
+
export function GuestOnly({ children, fallback, redirectTo }: GuardProps) {
|
|
53
|
+
const { isAuthenticated, isLoading } = useAuth();
|
|
54
|
+
|
|
55
|
+
if(redirectTo && !isLoading && isAuthenticated) {
|
|
56
|
+
router.push(redirectTo);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (isLoading || isAuthenticated) {
|
|
60
|
+
return fallback || <div></div>;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return <>{children}</>;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Hook para redirecionar baseado no status de autenticação
|
|
68
|
+
*/
|
|
69
|
+
export function useAuthRedirect(
|
|
70
|
+
authenticatedRedirect?: string,
|
|
71
|
+
unauthenticatedRedirect?: string
|
|
72
|
+
) {
|
|
73
|
+
const { isAuthenticated, isLoading } = useAuth();
|
|
74
|
+
|
|
75
|
+
React.useEffect(() => {
|
|
76
|
+
if (isLoading) return;
|
|
77
|
+
|
|
78
|
+
if (isAuthenticated && authenticatedRedirect) {
|
|
79
|
+
window.location.href = authenticatedRedirect;
|
|
80
|
+
} else if (!isAuthenticated && unauthenticatedRedirect) {
|
|
81
|
+
window.location.href = unauthenticatedRedirect;
|
|
82
|
+
}
|
|
83
|
+
}, [isAuthenticated, isLoading, authenticatedRedirect, unauthenticatedRedirect]);
|
|
84
|
+
}
|