celestya 0.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 +674 -0
- package/README.md +146 -0
- package/dist/client/index.d.mts +66 -0
- package/dist/client/index.d.ts +66 -0
- package/dist/client/index.js +238 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client/index.mjs +210 -0
- package/dist/client/index.mjs.map +1 -0
- package/dist/index.d.mts +49 -0
- package/dist/index.d.ts +49 -0
- package/dist/index.js +269 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +239 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +51 -0
package/README.md
ADDED
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
# celestya
|
|
2
|
+
|
|
3
|
+
Highly opinionated session management tool for NextJS Frontends
|
|
4
|
+
|
|
5
|
+
## How to use
|
|
6
|
+
|
|
7
|
+
Add environment vars (dont expose them publically!!)
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
//.env
|
|
11
|
+
|
|
12
|
+
CELESTYA_SECRET=XXXXXX // AT_LEAST_32_CHARACTERS
|
|
13
|
+
CELESTYA_COOKIE_NAME=XXXX // COOKIE_NAME
|
|
14
|
+
CELESTYA_SECURE=true // true / false
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Configure the api endpoints
|
|
18
|
+
|
|
19
|
+
```tsx
|
|
20
|
+
// /src/app/api/[[...endpoint]]
|
|
21
|
+
|
|
22
|
+
import { API_URL, HOST } from "@/config/env";
|
|
23
|
+
import { IConfig, IRequestOptions, Proxy } from "celestya";
|
|
24
|
+
|
|
25
|
+
const config: IConfig = {
|
|
26
|
+
host: HOST || "missing-host",
|
|
27
|
+
route: "/api",
|
|
28
|
+
apiUrl: API_URL || "missing-api-url",
|
|
29
|
+
userEndpoint: "/user",
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export const POST = (req: any, opt: IRequestOptions) => Proxy("POST", req, opt, config);
|
|
33
|
+
export const GET = (req: any, opt: IRequestOptions) => Proxy("GET", req, opt, config);
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Configure the provider
|
|
37
|
+
|
|
38
|
+
```tsx
|
|
39
|
+
// /src/app/layout.tsx
|
|
40
|
+
|
|
41
|
+
import { AuthProvider, Logout } from "celestya/client";
|
|
42
|
+
|
|
43
|
+
export default function RootLayout({
|
|
44
|
+
children,
|
|
45
|
+
}: {
|
|
46
|
+
children: React.ReactNode,
|
|
47
|
+
}) {
|
|
48
|
+
return (
|
|
49
|
+
<html lang="en">
|
|
50
|
+
<body>
|
|
51
|
+
<AuthProvider>{children}</AuthProvider>
|
|
52
|
+
</body>
|
|
53
|
+
</html>
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Use the getSession function in server components (keep in mind they dont revalidate often!)
|
|
59
|
+
|
|
60
|
+
```tsx
|
|
61
|
+
// /src/app/navbar.tsx
|
|
62
|
+
|
|
63
|
+
import { getSession, /* Session */ } from "celestya";
|
|
64
|
+
|
|
65
|
+
// Optionally provide a user object
|
|
66
|
+
interface User {
|
|
67
|
+
email: string
|
|
68
|
+
name: string
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const Navbar = async () => {
|
|
72
|
+
// const session: Session<User> = await getSession(); <- optional
|
|
73
|
+
const session = await getSession<User>();
|
|
74
|
+
|
|
75
|
+
return <div>Welcome: {session.user?.name}</div>;
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
export default Navbar;
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Use the apiFetch function in server components
|
|
82
|
+
|
|
83
|
+
```tsx
|
|
84
|
+
// /src/app/navbar.tsx
|
|
85
|
+
|
|
86
|
+
import { apiFetch } from "celestya";
|
|
87
|
+
import { config } from "@/app/api/[[...endpoint]]/route"
|
|
88
|
+
|
|
89
|
+
// Optionally provide a user object
|
|
90
|
+
interface User {
|
|
91
|
+
email: string
|
|
92
|
+
name: string
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const Navbar = async () => {
|
|
96
|
+
const user = await apiFetch("user", {}, config)
|
|
97
|
+
|
|
98
|
+
return <div>Welcome: {session.user?.name}</div>;
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
export default Navbar;
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
Use the other functions in client components
|
|
106
|
+
|
|
107
|
+
```tsx
|
|
108
|
+
// /src/app/page.tsx
|
|
109
|
+
|
|
110
|
+
import { useAuth } from 'celestya/client'
|
|
111
|
+
|
|
112
|
+
// Optionally provide a user object
|
|
113
|
+
interface User {
|
|
114
|
+
email: string
|
|
115
|
+
name: string
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const Home = async () => {
|
|
119
|
+
const { ready, get } = useAuth()
|
|
120
|
+
|
|
121
|
+
const handleClick = () => {
|
|
122
|
+
try {
|
|
123
|
+
if (!ready) throw new Error('Not ready')
|
|
124
|
+
const res = await get('/user/billing')
|
|
125
|
+
|
|
126
|
+
console.log(res)
|
|
127
|
+
} catch (e) {
|
|
128
|
+
console.log(e)
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
return <Button onClick={handleClick}>Welcome: {session.user?.name}</div>;
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
export default Navbar;
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## Todo
|
|
139
|
+
|
|
140
|
+
- [ ]: Upload request with worker as helper (?)
|
|
141
|
+
- [ ]: Refresh logic
|
|
142
|
+
- [x]: Change returns at error
|
|
143
|
+
- [x]: GET request with auth
|
|
144
|
+
- [x]: POST request with auth
|
|
145
|
+
- [x]: Fix issue with getSession serverside and config set at layout (If used at api/\_/route.tsx)
|
|
146
|
+
- [x]: Fix issue with api endpoints if no layout has been loaded (if accessing api directly)
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
|
|
3
|
+
declare module "iron-session" {
|
|
4
|
+
interface IronSessionData<U, T> {
|
|
5
|
+
user?: U;
|
|
6
|
+
token?: {
|
|
7
|
+
jwt: string;
|
|
8
|
+
refresh: string;
|
|
9
|
+
decoded: T;
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
interface ILoginData {
|
|
15
|
+
data: object;
|
|
16
|
+
redirect?: string;
|
|
17
|
+
onErrorUrl?: string;
|
|
18
|
+
}
|
|
19
|
+
interface IRegisterData {
|
|
20
|
+
data: object;
|
|
21
|
+
redirect?: string;
|
|
22
|
+
onErrorUrl?: string;
|
|
23
|
+
}
|
|
24
|
+
interface IOAuthData {
|
|
25
|
+
state: string;
|
|
26
|
+
oAuthUrl: string;
|
|
27
|
+
onErrorUrl?: string;
|
|
28
|
+
}
|
|
29
|
+
interface IResponseError {
|
|
30
|
+
error: string;
|
|
31
|
+
message: string;
|
|
32
|
+
}
|
|
33
|
+
interface IResponseSuccess<T, U> {
|
|
34
|
+
error: null;
|
|
35
|
+
data: T;
|
|
36
|
+
details: U;
|
|
37
|
+
}
|
|
38
|
+
interface IAuthContext<U> {
|
|
39
|
+
isLoggedIn: boolean;
|
|
40
|
+
ready: boolean;
|
|
41
|
+
user: U;
|
|
42
|
+
login: (data: ILoginData) => Promise<string>;
|
|
43
|
+
register: (data: IRegisterData) => Promise<string>;
|
|
44
|
+
oAuth: (data: IOAuthData) => Promise<string>;
|
|
45
|
+
logout: () => Promise<string>;
|
|
46
|
+
refreshUser: (force?: boolean) => Promise<void>;
|
|
47
|
+
get: <T, U = any>(url: string) => Promise<ResponseType<T, U>>;
|
|
48
|
+
post: <T, U = any>(url: string, body: any) => Promise<ResponseType<T, U>>;
|
|
49
|
+
del: <T, U = any>(url: string) => Promise<ResponseType<T, U>>;
|
|
50
|
+
}
|
|
51
|
+
interface IAuthContextOptions {
|
|
52
|
+
children: React.ReactNode;
|
|
53
|
+
routePrefix?: string;
|
|
54
|
+
}
|
|
55
|
+
interface IChildProps {
|
|
56
|
+
children?: React.ReactNode;
|
|
57
|
+
}
|
|
58
|
+
type ResponseType<T, U = any> = IResponseError | IResponseSuccess<T, U>;
|
|
59
|
+
|
|
60
|
+
type LogoutProps = React.FC<React.ComponentProps<'div'> & IChildProps>;
|
|
61
|
+
|
|
62
|
+
declare const AuthProvider: <IU>({ children, routePrefix, }: IAuthContextOptions) => react_jsx_runtime.JSX.Element;
|
|
63
|
+
declare const Logout: LogoutProps;
|
|
64
|
+
declare const useAuth: () => IAuthContext<any>;
|
|
65
|
+
|
|
66
|
+
export { AuthProvider, Logout, useAuth };
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
|
|
3
|
+
declare module "iron-session" {
|
|
4
|
+
interface IronSessionData<U, T> {
|
|
5
|
+
user?: U;
|
|
6
|
+
token?: {
|
|
7
|
+
jwt: string;
|
|
8
|
+
refresh: string;
|
|
9
|
+
decoded: T;
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
interface ILoginData {
|
|
15
|
+
data: object;
|
|
16
|
+
redirect?: string;
|
|
17
|
+
onErrorUrl?: string;
|
|
18
|
+
}
|
|
19
|
+
interface IRegisterData {
|
|
20
|
+
data: object;
|
|
21
|
+
redirect?: string;
|
|
22
|
+
onErrorUrl?: string;
|
|
23
|
+
}
|
|
24
|
+
interface IOAuthData {
|
|
25
|
+
state: string;
|
|
26
|
+
oAuthUrl: string;
|
|
27
|
+
onErrorUrl?: string;
|
|
28
|
+
}
|
|
29
|
+
interface IResponseError {
|
|
30
|
+
error: string;
|
|
31
|
+
message: string;
|
|
32
|
+
}
|
|
33
|
+
interface IResponseSuccess<T, U> {
|
|
34
|
+
error: null;
|
|
35
|
+
data: T;
|
|
36
|
+
details: U;
|
|
37
|
+
}
|
|
38
|
+
interface IAuthContext<U> {
|
|
39
|
+
isLoggedIn: boolean;
|
|
40
|
+
ready: boolean;
|
|
41
|
+
user: U;
|
|
42
|
+
login: (data: ILoginData) => Promise<string>;
|
|
43
|
+
register: (data: IRegisterData) => Promise<string>;
|
|
44
|
+
oAuth: (data: IOAuthData) => Promise<string>;
|
|
45
|
+
logout: () => Promise<string>;
|
|
46
|
+
refreshUser: (force?: boolean) => Promise<void>;
|
|
47
|
+
get: <T, U = any>(url: string) => Promise<ResponseType<T, U>>;
|
|
48
|
+
post: <T, U = any>(url: string, body: any) => Promise<ResponseType<T, U>>;
|
|
49
|
+
del: <T, U = any>(url: string) => Promise<ResponseType<T, U>>;
|
|
50
|
+
}
|
|
51
|
+
interface IAuthContextOptions {
|
|
52
|
+
children: React.ReactNode;
|
|
53
|
+
routePrefix?: string;
|
|
54
|
+
}
|
|
55
|
+
interface IChildProps {
|
|
56
|
+
children?: React.ReactNode;
|
|
57
|
+
}
|
|
58
|
+
type ResponseType<T, U = any> = IResponseError | IResponseSuccess<T, U>;
|
|
59
|
+
|
|
60
|
+
type LogoutProps = React.FC<React.ComponentProps<'div'> & IChildProps>;
|
|
61
|
+
|
|
62
|
+
declare const AuthProvider: <IU>({ children, routePrefix, }: IAuthContextOptions) => react_jsx_runtime.JSX.Element;
|
|
63
|
+
declare const Logout: LogoutProps;
|
|
64
|
+
declare const useAuth: () => IAuthContext<any>;
|
|
65
|
+
|
|
66
|
+
export { AuthProvider, Logout, useAuth };
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
"use strict";
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
20
|
+
|
|
21
|
+
// src/client/index.ts
|
|
22
|
+
var client_exports = {};
|
|
23
|
+
__export(client_exports, {
|
|
24
|
+
AuthProvider: () => AuthProvider,
|
|
25
|
+
Logout: () => Logout,
|
|
26
|
+
useAuth: () => useAuth
|
|
27
|
+
});
|
|
28
|
+
module.exports = __toCommonJS(client_exports);
|
|
29
|
+
|
|
30
|
+
// src/client/contextProvider.tsx
|
|
31
|
+
var import_react = require("react");
|
|
32
|
+
|
|
33
|
+
// src/client/request.ts
|
|
34
|
+
async function gFetch({
|
|
35
|
+
url,
|
|
36
|
+
options
|
|
37
|
+
}) {
|
|
38
|
+
const response = await fetch(url, {
|
|
39
|
+
method: "GET",
|
|
40
|
+
...options
|
|
41
|
+
});
|
|
42
|
+
return await response.json();
|
|
43
|
+
}
|
|
44
|
+
async function pFetch({
|
|
45
|
+
url,
|
|
46
|
+
body
|
|
47
|
+
}) {
|
|
48
|
+
const response = await fetch(url, {
|
|
49
|
+
method: "POST",
|
|
50
|
+
headers: { "Content-Type": "application/json" },
|
|
51
|
+
body: JSON.stringify(body)
|
|
52
|
+
});
|
|
53
|
+
return await response.json();
|
|
54
|
+
}
|
|
55
|
+
async function dFetch({
|
|
56
|
+
url,
|
|
57
|
+
options
|
|
58
|
+
}) {
|
|
59
|
+
const response = await fetch(url, {
|
|
60
|
+
method: "DELETE",
|
|
61
|
+
...options
|
|
62
|
+
});
|
|
63
|
+
return await response.json();
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// src/client/contextProvider.tsx
|
|
67
|
+
var import_navigation = require("next/navigation");
|
|
68
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
69
|
+
var AuthContext = (0, import_react.createContext)(null);
|
|
70
|
+
var AuthContextProvider = ({
|
|
71
|
+
children,
|
|
72
|
+
routePrefix = "/api"
|
|
73
|
+
}) => {
|
|
74
|
+
const [isLoggedIn, setIsLoggedIn] = (0, import_react.useState)(false);
|
|
75
|
+
const [ready, setReady] = (0, import_react.useState)(false);
|
|
76
|
+
const [user, setUser] = (0, import_react.useState)({});
|
|
77
|
+
const router = (0, import_navigation.useRouter)();
|
|
78
|
+
const loginRoute = routePrefix + "/login";
|
|
79
|
+
const registerRoute = routePrefix + "/register";
|
|
80
|
+
const logoutRoute = routePrefix + "/logout";
|
|
81
|
+
const userRoute = routePrefix + "/user";
|
|
82
|
+
const oAuthRoute = routePrefix + "/oauth";
|
|
83
|
+
const proxyRoute = routePrefix + "/proxy";
|
|
84
|
+
const login = async (loginData) => {
|
|
85
|
+
try {
|
|
86
|
+
const res = await pFetch({
|
|
87
|
+
url: loginRoute,
|
|
88
|
+
body: loginData.data
|
|
89
|
+
});
|
|
90
|
+
setIsLoggedIn(true);
|
|
91
|
+
if (res.error)
|
|
92
|
+
throw new Error(res.message);
|
|
93
|
+
return loginData.redirect || "/";
|
|
94
|
+
} catch (e) {
|
|
95
|
+
return `${loginData.onErrorUrl || "/"}?error=${e.message}`;
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
const register = async (registerData) => {
|
|
99
|
+
try {
|
|
100
|
+
const res = await pFetch({
|
|
101
|
+
url: registerRoute,
|
|
102
|
+
body: registerData.data
|
|
103
|
+
});
|
|
104
|
+
if (res.error)
|
|
105
|
+
throw new Error(res.message);
|
|
106
|
+
return `${registerData.redirect || "/"}?success=true`;
|
|
107
|
+
} catch (e) {
|
|
108
|
+
return `${registerData.onErrorUrl || "/"}?error=${e.message}`;
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
const oAuth = async ({
|
|
112
|
+
state,
|
|
113
|
+
oAuthUrl,
|
|
114
|
+
onErrorUrl
|
|
115
|
+
}) => {
|
|
116
|
+
try {
|
|
117
|
+
const url = new URL(oAuthRoute, "http://localhost/");
|
|
118
|
+
url.searchParams.set("authUrl", oAuthUrl);
|
|
119
|
+
if (state && state !== "/")
|
|
120
|
+
url.searchParams.set("state", state);
|
|
121
|
+
const response = await gFetch({ url: url.pathname + url.search });
|
|
122
|
+
return response.data;
|
|
123
|
+
} catch (e) {
|
|
124
|
+
return `${onErrorUrl || "/"}?error=${e.message}`;
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
const logout = async () => {
|
|
128
|
+
try {
|
|
129
|
+
const data = await gFetch({
|
|
130
|
+
url: logoutRoute,
|
|
131
|
+
options: { cache: "no-store" }
|
|
132
|
+
});
|
|
133
|
+
setIsLoggedIn(false);
|
|
134
|
+
setUser({});
|
|
135
|
+
return data.data;
|
|
136
|
+
} catch (e) {
|
|
137
|
+
console.log(e);
|
|
138
|
+
return "/";
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
const refreshUser = async (force) => {
|
|
142
|
+
try {
|
|
143
|
+
const data = await gFetch({
|
|
144
|
+
url: `${userRoute}${force ? "?force=true" : ""}`,
|
|
145
|
+
options: { cache: "no-store" }
|
|
146
|
+
});
|
|
147
|
+
if (!data.error) {
|
|
148
|
+
setUser(data.data);
|
|
149
|
+
setIsLoggedIn(true);
|
|
150
|
+
} else {
|
|
151
|
+
setUser({});
|
|
152
|
+
setIsLoggedIn(false);
|
|
153
|
+
}
|
|
154
|
+
setReady(true);
|
|
155
|
+
router.refresh();
|
|
156
|
+
} catch (e) {
|
|
157
|
+
console.log("refreshUser error: ", e);
|
|
158
|
+
}
|
|
159
|
+
};
|
|
160
|
+
const get = async (url) => {
|
|
161
|
+
try {
|
|
162
|
+
const r = await gFetch({ url: `${proxyRoute}${url}` });
|
|
163
|
+
return r;
|
|
164
|
+
} catch (e) {
|
|
165
|
+
return { error: "getRequestError", message: e.message };
|
|
166
|
+
}
|
|
167
|
+
};
|
|
168
|
+
const post = async (url, body) => {
|
|
169
|
+
try {
|
|
170
|
+
const r = await pFetch({
|
|
171
|
+
url: `${proxyRoute}${url}`,
|
|
172
|
+
body
|
|
173
|
+
});
|
|
174
|
+
return r;
|
|
175
|
+
} catch (e) {
|
|
176
|
+
return { error: "getRequestError", message: e.message };
|
|
177
|
+
}
|
|
178
|
+
};
|
|
179
|
+
const del = async (url) => {
|
|
180
|
+
try {
|
|
181
|
+
const r = await dFetch({ url: `${proxyRoute}${url}` });
|
|
182
|
+
return r;
|
|
183
|
+
} catch (e) {
|
|
184
|
+
return { error: "getRequestError", message: e.message };
|
|
185
|
+
}
|
|
186
|
+
};
|
|
187
|
+
(0, import_react.useEffect)(() => {
|
|
188
|
+
if (!ready)
|
|
189
|
+
refreshUser();
|
|
190
|
+
}, []);
|
|
191
|
+
const provider = {
|
|
192
|
+
ready,
|
|
193
|
+
login,
|
|
194
|
+
register,
|
|
195
|
+
logout,
|
|
196
|
+
isLoggedIn,
|
|
197
|
+
refreshUser,
|
|
198
|
+
user,
|
|
199
|
+
oAuth,
|
|
200
|
+
get,
|
|
201
|
+
post,
|
|
202
|
+
del
|
|
203
|
+
/* upload, */
|
|
204
|
+
};
|
|
205
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AuthContext.Provider, { value: provider, children });
|
|
206
|
+
};
|
|
207
|
+
var contextProvider_default = AuthContextProvider;
|
|
208
|
+
|
|
209
|
+
// src/client/useAuth.ts
|
|
210
|
+
var import_react2 = require("react");
|
|
211
|
+
var useAuthContext = () => {
|
|
212
|
+
return (0, import_react2.useContext)(AuthContext);
|
|
213
|
+
};
|
|
214
|
+
var useAuth_default = useAuthContext;
|
|
215
|
+
|
|
216
|
+
// src/client/Logout.tsx
|
|
217
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
218
|
+
var LogoutComponent = ({ children, ...props }) => {
|
|
219
|
+
const { logout } = useAuth_default();
|
|
220
|
+
const handleLogout = async (e) => {
|
|
221
|
+
e.preventDefault();
|
|
222
|
+
await logout();
|
|
223
|
+
};
|
|
224
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { onClick: handleLogout, ...props, children });
|
|
225
|
+
};
|
|
226
|
+
var Logout_default = LogoutComponent;
|
|
227
|
+
|
|
228
|
+
// src/client/index.ts
|
|
229
|
+
var AuthProvider = contextProvider_default;
|
|
230
|
+
var Logout = Logout_default;
|
|
231
|
+
var useAuth = useAuth_default;
|
|
232
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
233
|
+
0 && (module.exports = {
|
|
234
|
+
AuthProvider,
|
|
235
|
+
Logout,
|
|
236
|
+
useAuth
|
|
237
|
+
});
|
|
238
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/client/index.ts","../../src/client/contextProvider.tsx","../../src/client/request.ts","../../src/client/useAuth.ts","../../src/client/Logout.tsx"],"sourcesContent":["import AuthContextProvider from \"./contextProvider\";\nimport LogoutComponent from \"./Logout\";\nimport useAuthContext from \"./useAuth\";\n\nexport const AuthProvider = AuthContextProvider;\nexport const Logout = LogoutComponent;\nexport const useAuth = useAuthContext;\n","\"use client\";\n\nimport { createContext, useEffect, useState } from \"react\";\nimport {\n IAuthContext,\n IAuthContextOptions,\n ILoginData,\n IOAuthData,\n IRegisterData,\n ResponseType,\n} from \"../types/internal\";\n\nimport { dFetch, gFetch, pFetch } from \"./request\";\n\nimport { useRouter } from \"next/navigation\";\n/* +\n Frontend context for providing login, logout, register and refresh\n 'use client' needed for using -> client components only\n server components need to use useSession()\n*/\n\nexport const AuthContext = createContext<IAuthContext<any>>(null as any);\n\nconst AuthContextProvider = <IU,>({\n children,\n routePrefix = \"/api\",\n}: IAuthContextOptions) => {\n const [isLoggedIn, setIsLoggedIn] = useState(false);\n const [ready, setReady] = useState(false);\n const [user, setUser] = useState<IU | {}>({});\n\n const router = useRouter();\n\n // POST /session/login\n const loginRoute = routePrefix + \"/login\";\n\n // POST /session/refresh\n const registerRoute = routePrefix + \"/register\";\n\n // GET /session/logout\n const logoutRoute = routePrefix + \"/logout\";\n\n // GET /session\n const userRoute = routePrefix + \"/user\";\n\n // GET /session/oauth/API_OAUTH_URL\n const oAuthRoute = routePrefix + \"/oauth\";\n\n // GET/POST/DELETE /proxy/URL\n const proxyRoute = routePrefix + \"/proxy\";\n\n const login = async (loginData: ILoginData): Promise<string> => {\n try {\n const res = await pFetch({\n url: loginRoute,\n body: loginData.data,\n });\n\n setIsLoggedIn(true);\n\n if (res.error) throw new Error(res.message);\n\n return loginData.redirect || \"/\";\n } catch (e: any) {\n return `${loginData.onErrorUrl || \"/\"}?error=${e.message}`;\n }\n };\n\n const register = async (registerData: IRegisterData): Promise<string> => {\n try {\n const res = await pFetch({\n url: registerRoute,\n body: registerData.data,\n });\n\n if (res.error) throw new Error(res.message);\n\n return `${registerData.redirect || \"/\"}?success=true`;\n } catch (e: any) {\n return `${registerData.onErrorUrl || \"/\"}?error=${e.message}`;\n }\n };\n\n const oAuth = async ({\n state,\n oAuthUrl,\n onErrorUrl,\n }: IOAuthData): Promise<string> => {\n try {\n const url = new URL(oAuthRoute, \"http://localhost/\");\n\n url.searchParams.set(\"authUrl\", oAuthUrl);\n\n if (state && state !== \"/\") url.searchParams.set(\"state\", state);\n\n const response = await gFetch({ url: url.pathname + url.search });\n\n return response.data;\n } catch (e: any) {\n return `${onErrorUrl || \"/\"}?error=${e.message}`;\n }\n };\n\n const logout = async (): Promise<string> => {\n try {\n const data = await gFetch({\n url: logoutRoute,\n options: { cache: \"no-store\" },\n });\n\n setIsLoggedIn(false);\n setUser({});\n\n return data.data;\n } catch (e: any) {\n console.log(e);\n return \"/\";\n }\n };\n\n const refreshUser = async (force?: boolean): Promise<void> => {\n try {\n const data = await gFetch({\n url: `${userRoute}${force ? \"?force=true\" : \"\"}`,\n options: { cache: \"no-store\" },\n });\n\n if (!data.error) {\n setUser(data.data);\n setIsLoggedIn(true);\n } else {\n setUser({});\n setIsLoggedIn(false);\n }\n\n setReady(true);\n\n router.refresh();\n } catch (e) {\n console.log(\"refreshUser error: \", e);\n }\n };\n\n const get = async <T, U>(url: string): Promise<ResponseType<T, U>> => {\n try {\n const r = await gFetch({ url: `${proxyRoute}${url}` });\n\n return r;\n } catch (e: any) {\n return { error: \"getRequestError\", message: e.message };\n }\n };\n\n const post = async <T, U = any>(\n url: string,\n body: any\n ): Promise<ResponseType<T, U>> => {\n try {\n const r = await pFetch({\n url: `${proxyRoute}${url}`,\n body,\n });\n\n return r;\n } catch (e: any) {\n return { error: \"getRequestError\", message: e.message };\n }\n };\n\n const del = async <T, U>(url: string): Promise<ResponseType<T, U>> => {\n try {\n const r = await dFetch({ url: `${proxyRoute}${url}` });\n\n return r;\n } catch (e: any) {\n return { error: \"getRequestError\", message: e.message };\n }\n };\n\n /**\n * Can only be used if user is logged in! and already initialised\n * @param url url for upload\n * @param formData form data\n * @param setProgress progress dispatch\n * @returns object with data or error\n */\n /* const upload = async <T, U = any>(\n url: string,\n formName: string,\n files: File[],\n setProgress: (p: number) => void,\n ): Promise<TRequest<T, U>> => {\n try {\n if (!user.token) throw new Error('user not logged in')\n \n const res: Error | XMLHttpRequest = await new Promise(\n (resolve, reject) => {\n try {\n const xhr = new XMLHttpRequest()\n const formData = new FormData()\n \n for (let i = 0; i < files.length; i++)\n formData.append(formName, files[i])\n \n xhr.open('POST', `${API_URL}${url}`, true)\n xhr.setRequestHeader('Authorization', `Bearer ${user.token}`)\n xhr.upload.onprogress = (ev: ProgressEvent<EventTarget>) => {\n if (ev.lengthComputable) {\n const percentComplete = (ev.loaded / ev.total) * 100\n setProgress(percentComplete)\n }\n }\n \n xhr.onload = function () {\n console.log('break3?', this)\n return this.status === 200\n ? resolve(this)\n : reject(new Error('Error while uploading: ' + this.status))\n }\n \n xhr.onerror = (ev: ProgressEvent<EventTarget>) => {\n console.log('break2', ev.target)\n reject(ev)\n }\n \n xhr.send(formData)\n } catch (e) {\n console.log('break1', e)\n reject(e)\n }\n },\n )\n \n if (res instanceof Error) throw res\n \n const data: any = JSON.parse(res.responseText)\n \n if (data.error) throw new Error(data.data)\n \n return { data: data.data }\n } catch (e) {\n console.log('break4', e)\n return { error: e.message || 'upload error' }\n }\n }\n \n const getContext = () => {\n let context = user.id\n \n if (!user.id) {\n // if not logged in\n const cookie = document.cookie\n .split(';')\n .find((c) => c.includes('cycle_cid'))\n \n if (cookie) {\n // use cookie value\n context = cookie.split('=')[1]\n } else {\n // set new cookie\n context =\n Math.random().toString(36).substring(2, 15) +\n Math.random().toString(36).substring(2, 15)\n \n document.cookie = `cycle_cid=${context};path=/;max-age=31536000`\n }\n }\n \n return context\n }\n \n const event = async (name: string, value?: any): Promise<boolean> => {\n try {\n const contextId = getContext()\n \n const r = await fetch(NOFY_API_URL + '/event', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: 'Basic ' + ANALYTICS_KEY,\n },\n body: JSON.stringify({\n source: IS_PROD ? 'cycle-frontend' : 'cycle-frontend-dev',\n contextId,\n name,\n value,\n }),\n })\n \n const res = await r.json()\n if (res.error) throw new Error(res.error)\n \n return true\n } catch (e) {\n console.log('#> event error: ', e)\n return false\n }\n }\n \n const pageView = async (url: string, referer?: string): Promise<boolean> => {\n try {\n const contextId = getContext()\n \n const r = await fetch(NOFY_API_URL + '/log/count', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: 'Basic ' + ANALYTICS_KEY,\n },\n body: JSON.stringify({\n meta: {\n contextId,\n type: 'pageview',\n },\n referer,\n identifier: url,\n }),\n })\n \n const res = await r.json()\n if (res.error) throw new Error(res.error)\n \n return true\n } catch (e) {\n console.log('#> event error: ', e)\n return false\n }\n } */\n\n useEffect(() => {\n if (!ready) refreshUser();\n }, []);\n\n const provider = {\n ready,\n login,\n register,\n logout,\n isLoggedIn,\n refreshUser,\n user,\n oAuth,\n get,\n post,\n del,\n /* upload, */\n };\n\n return (\n <AuthContext.Provider value={provider}>{children}</AuthContext.Provider>\n );\n};\n\nexport default AuthContextProvider;\n","export async function gFetch({\n url,\n options,\n}: {\n url: string | URL;\n options?: object;\n}) {\n const response: Response = await fetch(url, {\n method: \"GET\",\n ...options,\n });\n\n return await response.json();\n}\n\nexport async function pFetch({\n url,\n body,\n}: {\n url: string | URL;\n body: object;\n}) {\n const response: Response = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n });\n\n return await response.json();\n}\n\nexport async function dFetch({\n url,\n options,\n}: {\n url: string | URL;\n options?: object;\n}) {\n const response: Response = await fetch(url, {\n method: \"DELETE\",\n ...options,\n });\n\n return await response.json();\n}\n","import { useContext } from \"react\";\nimport { AuthContext } from \"./contextProvider\";\n\nconst useAuthContext = () => {\n return useContext(AuthContext);\n};\n\nexport default useAuthContext;\n","'use client'\n\nimport { IChildProps } from \"../types/internal\";\nimport useAuthContext from \"./useAuth\";\n\nexport type LogoutProps = React.FC<React.ComponentProps<'div'> & IChildProps>\n\nconst LogoutComponent: LogoutProps = ({ children, ...props }) => {\n const { logout } = useAuthContext()\n\n const handleLogout = async (e: any) => {\n e.preventDefault()\n await logout()\n }\n\n return (\n <div onClick={handleLogout} {...props}>\n {children}\n </div>\n )\n}\n\nexport default LogoutComponent"],"mappings":"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","names":["import_react","import_jsx_runtime"]}
|