@auditauth/next 0.1.9 → 0.2.0-beta.2
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/README.md +132 -1
- package/dist/facade/createAuditAuth.d.ts +29 -0
- package/dist/facade/createAuditAuth.js +52 -0
- package/dist/facade/index.d.ts +1 -0
- package/dist/facade/index.js +1 -0
- package/dist/guard.d.ts +1 -1
- package/dist/guard.js +1 -1
- package/dist/helpers.js +1 -1
- package/dist/index.d.ts +6 -5
- package/dist/index.js +5 -4
- package/dist/request.js +27 -19
- package/dist/sdk.d.ts +14 -26
- package/dist/sdk.js +134 -192
- package/dist/settings.d.ts +16 -19
- package/dist/settings.js +3 -22
- package/dist/types.d.ts +2 -40
- package/package.json +30 -8
- package/LICENSE +0 -21
package/README.md
CHANGED
|
@@ -1,3 +1,134 @@
|
|
|
1
1
|
# @auditauth/next
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
`@auditauth/next` is the AuditAuth integration for Next.js App Router. It
|
|
4
|
+
provides route handlers, auth middleware, protected server handlers, session
|
|
5
|
+
helpers, and authenticated fetch wrappers.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
Install the package in your Next.js application.
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install @auditauth/next
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Create the AuditAuth provider
|
|
16
|
+
|
|
17
|
+
Create one shared instance with `createAuditAuthNext()`.
|
|
18
|
+
|
|
19
|
+
```ts
|
|
20
|
+
// src/providers/auth.ts
|
|
21
|
+
import { createAuditAuthNext } from '@auditauth/next'
|
|
22
|
+
|
|
23
|
+
export const auditauth = createAuditAuthNext({
|
|
24
|
+
apiKey: process.env.AUDITAUTH_API_KEY!,
|
|
25
|
+
appId: process.env.AUDITAUTH_APP_ID!,
|
|
26
|
+
baseUrl: 'http://localhost:3000',
|
|
27
|
+
redirectUrl: 'http://localhost:3000/private',
|
|
28
|
+
})
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Register auth API handlers
|
|
32
|
+
|
|
33
|
+
Expose the SDK handlers through a catch-all route.
|
|
34
|
+
|
|
35
|
+
```ts
|
|
36
|
+
// src/app/api/auditauth/[...auditauth]/route.ts
|
|
37
|
+
import { auditauth } from '@/providers/auth'
|
|
38
|
+
|
|
39
|
+
export const { GET, POST } = auditauth.handlers
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
The handler covers these endpoints:
|
|
43
|
+
|
|
44
|
+
- `GET /api/auditauth/login`
|
|
45
|
+
- `GET /api/auditauth/callback`
|
|
46
|
+
- `GET /api/auditauth/logout`
|
|
47
|
+
- `GET /api/auditauth/portal`
|
|
48
|
+
- `GET /api/auditauth/session`
|
|
49
|
+
- `GET /api/auditauth/refresh`
|
|
50
|
+
- `POST /api/auditauth/metrics`
|
|
51
|
+
|
|
52
|
+
## Protect private routes with middleware
|
|
53
|
+
|
|
54
|
+
Call `auditauth.middleware()` on route groups that require authentication.
|
|
55
|
+
|
|
56
|
+
```ts
|
|
57
|
+
// src/proxy.ts
|
|
58
|
+
import { NextResponse, type NextRequest } from 'next/server'
|
|
59
|
+
import { auditauth } from '@/providers/auth'
|
|
60
|
+
|
|
61
|
+
export async function proxy(request: NextRequest) {
|
|
62
|
+
if (request.nextUrl.pathname.startsWith('/private')) {
|
|
63
|
+
return auditauth.middleware(request)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return NextResponse.next()
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Access session data in server components
|
|
71
|
+
|
|
72
|
+
Use `auditauth.getSession()` in server components, route handlers, or server
|
|
73
|
+
actions.
|
|
74
|
+
|
|
75
|
+
```ts
|
|
76
|
+
const session = await auditauth.getSession()
|
|
77
|
+
if (!session) return null
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Protect custom route handlers
|
|
81
|
+
|
|
82
|
+
Wrap handlers with `auditauth.withAuthRequest()` to enforce token validation and
|
|
83
|
+
inject the verified token payload.
|
|
84
|
+
|
|
85
|
+
```ts
|
|
86
|
+
import { auditauth } from '@/providers/auth'
|
|
87
|
+
import { NextResponse } from 'next/server'
|
|
88
|
+
|
|
89
|
+
export const GET = auditauth.withAuthRequest(async (_req, _ctx, session) => {
|
|
90
|
+
return NextResponse.json({ email: session.email })
|
|
91
|
+
})
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Call protected APIs from the server
|
|
95
|
+
|
|
96
|
+
Use `auditauth.fetch()` for server-side requests with automatic refresh and
|
|
97
|
+
request metrics.
|
|
98
|
+
|
|
99
|
+
```ts
|
|
100
|
+
const response = await auditauth.fetch('https://api.example.com/private')
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Client helpers
|
|
104
|
+
|
|
105
|
+
For client-side navigation shortcuts, import these helpers:
|
|
106
|
+
|
|
107
|
+
- `login()`
|
|
108
|
+
- `logout()`
|
|
109
|
+
- `goToPortal()`
|
|
110
|
+
|
|
111
|
+
You can also use `AuditAuthGuard` and `useAuditAuth` to gate client-rendered
|
|
112
|
+
UI sections.
|
|
113
|
+
|
|
114
|
+
## Compatibility
|
|
115
|
+
|
|
116
|
+
This package requires:
|
|
117
|
+
|
|
118
|
+
- Node.js `>=18.18.0`
|
|
119
|
+
- Next.js `>=13`
|
|
120
|
+
- React `>=18`
|
|
121
|
+
- React DOM `>=18`
|
|
122
|
+
|
|
123
|
+
## Resources
|
|
124
|
+
|
|
125
|
+
- Repository: https://github.com/nimibyte/auditauth-sdk
|
|
126
|
+
- Documentation: https://docs.auditauth.com
|
|
127
|
+
|
|
128
|
+
## Example
|
|
129
|
+
|
|
130
|
+
See `examples/next` for a complete App Router integration.
|
|
131
|
+
|
|
132
|
+
## License
|
|
133
|
+
|
|
134
|
+
MIT
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { NextRequest } from 'next/server.js';
|
|
2
|
+
import { NextResponse } from 'next/server.js';
|
|
3
|
+
import type { AuditAuthConfig, SessionUser } from '@auditauth/core';
|
|
4
|
+
import type { AuditAuthTokenPayload } from '@auditauth/node';
|
|
5
|
+
type AuditAuthNextFacade = {
|
|
6
|
+
handlers: {
|
|
7
|
+
GET: (req: NextRequest, ctx: {
|
|
8
|
+
params: Promise<{
|
|
9
|
+
auditauth: string[];
|
|
10
|
+
}>;
|
|
11
|
+
}) => Promise<Response>;
|
|
12
|
+
POST: (req: NextRequest, ctx: {
|
|
13
|
+
params: Promise<{
|
|
14
|
+
auditauth: string[];
|
|
15
|
+
}>;
|
|
16
|
+
}) => Promise<Response>;
|
|
17
|
+
};
|
|
18
|
+
middleware: (req: NextRequest) => Promise<NextResponse>;
|
|
19
|
+
getSession: () => Promise<SessionUser | null>;
|
|
20
|
+
hasSession: () => Promise<boolean>;
|
|
21
|
+
fetch: (url: string, init?: RequestInit) => Promise<Response>;
|
|
22
|
+
getLoginUrl: () => URL;
|
|
23
|
+
getLogoutUrl: () => URL;
|
|
24
|
+
getPortalUrl: () => URL;
|
|
25
|
+
withAuthRequest: <C>(handler: (req: NextRequest, ctx: C, session: AuditAuthTokenPayload) => Promise<Response>) => (req: NextRequest, ctx: C) => Promise<Response>;
|
|
26
|
+
};
|
|
27
|
+
declare function createAuditAuthNext(config: AuditAuthConfig): AuditAuthNextFacade;
|
|
28
|
+
export type { AuditAuthNextFacade };
|
|
29
|
+
export { createAuditAuthNext };
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { cookies } from 'next/headers.js';
|
|
2
|
+
import { AuditAuthNext } from '../sdk.js';
|
|
3
|
+
import { SETTINGS } from '../settings.js';
|
|
4
|
+
function createAuditAuthNext(config) {
|
|
5
|
+
const base = new URL(config.baseUrl);
|
|
6
|
+
async function createInstance() {
|
|
7
|
+
const store = await cookies();
|
|
8
|
+
return new AuditAuthNext(config, {
|
|
9
|
+
get: (name) => store.get(name)?.value,
|
|
10
|
+
set: (name, value, options) => store.set(name, value, options),
|
|
11
|
+
remove: (name) => store.delete(name),
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
return {
|
|
15
|
+
handlers: {
|
|
16
|
+
GET: async (req, ctx) => {
|
|
17
|
+
const instance = await createInstance();
|
|
18
|
+
return instance.getHandlers().GET(req, ctx);
|
|
19
|
+
},
|
|
20
|
+
POST: async (req, ctx) => {
|
|
21
|
+
const instance = await createInstance();
|
|
22
|
+
return instance.getHandlers().POST(req, ctx);
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
middleware: async (req) => {
|
|
26
|
+
const instance = await createInstance();
|
|
27
|
+
return instance.middleware(req);
|
|
28
|
+
},
|
|
29
|
+
getSession: async () => {
|
|
30
|
+
const instance = await createInstance();
|
|
31
|
+
return instance.getSession();
|
|
32
|
+
},
|
|
33
|
+
hasSession: async () => {
|
|
34
|
+
const instance = await createInstance();
|
|
35
|
+
return instance.hasSession();
|
|
36
|
+
},
|
|
37
|
+
fetch: async (url, init) => {
|
|
38
|
+
const instance = await createInstance();
|
|
39
|
+
return instance.fetch(url, init);
|
|
40
|
+
},
|
|
41
|
+
withAuthRequest: (handler) => {
|
|
42
|
+
return async (req, ctx) => {
|
|
43
|
+
const instance = await createInstance();
|
|
44
|
+
return instance.withAuthRequest(handler)(req, ctx);
|
|
45
|
+
};
|
|
46
|
+
},
|
|
47
|
+
getLoginUrl: () => new URL(SETTINGS.bff.paths.login, base),
|
|
48
|
+
getLogoutUrl: () => new URL(SETTINGS.bff.paths.logout, base),
|
|
49
|
+
getPortalUrl: () => new URL(SETTINGS.bff.paths.portal, base),
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
export { createAuditAuthNext };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './createAuditAuth.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './createAuditAuth.js';
|
package/dist/guard.d.ts
CHANGED
package/dist/guard.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
3
|
import { createContext, useContext, useEffect, useMemo, useState } from "react";
|
|
4
|
-
import { SETTINGS } from
|
|
4
|
+
import { SETTINGS } from './settings.js';
|
|
5
5
|
const AuthContext = createContext(null);
|
|
6
6
|
const useAuditAuth = () => {
|
|
7
7
|
const ctx = useContext(AuthContext);
|
package/dist/helpers.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/* -------------------------------------------------------------------------- */
|
|
2
2
|
/* CLIENT SHORTCUTS */
|
|
3
3
|
/* -------------------------------------------------------------------------- */
|
|
4
|
-
import { SETTINGS } from
|
|
4
|
+
import { SETTINGS } from './settings.js';
|
|
5
5
|
const login = () => {
|
|
6
6
|
window.location.href = SETTINGS.bff.paths.login;
|
|
7
7
|
};
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
export { AuditAuthNext } from './sdk';
|
|
2
|
-
export { AuditAuthGuard, useAuditAuth } from './guard';
|
|
3
|
-
export { login, logout, goToPortal } from './helpers';
|
|
4
|
-
export { auditauthFetch } from './request';
|
|
5
|
-
export type * from './types';
|
|
1
|
+
export { AuditAuthNext } from './sdk.js';
|
|
2
|
+
export { AuditAuthGuard, useAuditAuth } from './guard.js';
|
|
3
|
+
export { login, logout, goToPortal } from './helpers.js';
|
|
4
|
+
export { auditauthFetch } from './request.js';
|
|
5
|
+
export type * from './types.js';
|
|
6
|
+
export * from './facade/index.js';
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
export { AuditAuthNext } from './sdk';
|
|
2
|
-
export { AuditAuthGuard, useAuditAuth } from './guard';
|
|
3
|
-
export { login, logout, goToPortal } from './helpers';
|
|
4
|
-
export { auditauthFetch } from './request';
|
|
1
|
+
export { AuditAuthNext } from './sdk.js';
|
|
2
|
+
export { AuditAuthGuard, useAuditAuth } from './guard.js';
|
|
3
|
+
export { login, logout, goToPortal } from './helpers.js';
|
|
4
|
+
export { auditauthFetch } from './request.js';
|
|
5
|
+
export * from './facade/index.js';
|
package/dist/request.js
CHANGED
|
@@ -1,10 +1,25 @@
|
|
|
1
1
|
'use server';
|
|
2
|
-
import { cookies } from
|
|
3
|
-
import { SETTINGS } from
|
|
2
|
+
import { cookies } from 'next/headers.js';
|
|
3
|
+
import { SETTINGS } from './settings.js';
|
|
4
|
+
import { headers } from 'next/headers.js';
|
|
5
|
+
import { refreshTokens } from "@auditauth/core";
|
|
6
|
+
const getRequestOrigin = async () => {
|
|
7
|
+
const h = await headers();
|
|
8
|
+
const proto = h.get('x-forwarded-proto') ??
|
|
9
|
+
(process.env.NODE_ENV === 'production' ? 'https' : 'http');
|
|
10
|
+
const host = h.get('x-forwarded-host') ??
|
|
11
|
+
h.get('host');
|
|
12
|
+
if (!host) {
|
|
13
|
+
throw new Error('Cannot resolve request origin');
|
|
14
|
+
}
|
|
15
|
+
return `${proto}://${host}`;
|
|
16
|
+
};
|
|
4
17
|
const auditauthFetch = async (url, init = {}) => {
|
|
5
18
|
const cookieManager = await cookies();
|
|
6
|
-
const
|
|
7
|
-
const
|
|
19
|
+
const origin = await getRequestOrigin();
|
|
20
|
+
const access_token = cookieManager.get(SETTINGS.storage_keys.access)?.value;
|
|
21
|
+
const refresh_token = cookieManager.get(SETTINGS.storage_keys.refresh)?.value;
|
|
22
|
+
const session_id = cookieManager.get(SETTINGS.storage_keys.session_id)?.value;
|
|
8
23
|
const doFetch = (token) => fetch(url, {
|
|
9
24
|
...init,
|
|
10
25
|
headers: {
|
|
@@ -13,21 +28,14 @@ const auditauthFetch = async (url, init = {}) => {
|
|
|
13
28
|
},
|
|
14
29
|
});
|
|
15
30
|
const start = performance.now();
|
|
16
|
-
let response = await doFetch(access_token
|
|
31
|
+
let response = await doFetch(access_token);
|
|
17
32
|
if (response.status === 401 && refresh_token) {
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
headers: { 'Content-Type': 'application/json' },
|
|
21
|
-
body: JSON.stringify({
|
|
22
|
-
refresh_token,
|
|
23
|
-
client_type: 'server',
|
|
24
|
-
}),
|
|
25
|
-
});
|
|
26
|
-
if (!refreshResponse.ok)
|
|
33
|
+
const refreshData = await refreshTokens({ refresh_token, client_type: 'server' });
|
|
34
|
+
if (!refreshData) {
|
|
27
35
|
return response;
|
|
28
|
-
|
|
29
|
-
if (
|
|
30
|
-
response = await doFetch(
|
|
36
|
+
}
|
|
37
|
+
if (refreshData.access_token && refreshData.refresh_token) {
|
|
38
|
+
response = await doFetch(refreshData.access_token);
|
|
31
39
|
}
|
|
32
40
|
}
|
|
33
41
|
queueMicrotask(() => {
|
|
@@ -42,10 +50,10 @@ const auditauthFetch = async (url, init = {}) => {
|
|
|
42
50
|
duration_ms: Math.round(performance.now() - start),
|
|
43
51
|
},
|
|
44
52
|
};
|
|
45
|
-
fetch(`${SETTINGS.bff.paths.metrics}`, {
|
|
53
|
+
fetch(`${origin}${SETTINGS.bff.paths.metrics}`, {
|
|
46
54
|
method: 'POST',
|
|
47
55
|
headers: { 'Content-Type': 'application/json' },
|
|
48
|
-
body: JSON.stringify({ ...payload }),
|
|
56
|
+
body: JSON.stringify({ ...payload, session_id }),
|
|
49
57
|
}).catch(() => { });
|
|
50
58
|
});
|
|
51
59
|
return response;
|
package/dist/sdk.d.ts
CHANGED
|
@@ -1,36 +1,24 @@
|
|
|
1
|
-
import { NextRequest, NextResponse } from
|
|
2
|
-
import {
|
|
1
|
+
import { NextRequest, NextResponse } from 'next/server.js';
|
|
2
|
+
import type { CookieAdapter } from './types.js';
|
|
3
|
+
import { AuditAuthConfig, SessionUser } from '@auditauth/core';
|
|
4
|
+
import { AuditAuthTokenPayload } from "@auditauth/node";
|
|
3
5
|
declare class AuditAuthNext {
|
|
4
6
|
private config;
|
|
5
7
|
private cookies;
|
|
6
8
|
constructor(config: AuditAuthConfig, cookies: CookieAdapter);
|
|
7
|
-
verifyAccessToken(token: string): Promise<boolean>;
|
|
8
9
|
private getCookieTokens;
|
|
9
10
|
private setCookieTokens;
|
|
11
|
+
private pushMetric;
|
|
10
12
|
getSession(): SessionUser | null;
|
|
11
13
|
hasSession(): boolean;
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
url: null;
|
|
21
|
-
reason: string;
|
|
22
|
-
} | {
|
|
23
|
-
ok: boolean;
|
|
24
|
-
url: string;
|
|
25
|
-
reason: null;
|
|
26
|
-
}>;
|
|
27
|
-
private refreshRequest;
|
|
28
|
-
request(url: string, init?: RequestInit): Promise<Response>;
|
|
29
|
-
metrics(payload: Metric): Promise<Response>;
|
|
30
|
-
private pushMetric;
|
|
31
|
-
refresh(): Promise<{
|
|
32
|
-
ok: boolean;
|
|
33
|
-
}>;
|
|
14
|
+
getLoginUrl(): URL;
|
|
15
|
+
getLogoutUrl(): URL;
|
|
16
|
+
getPortalUrl(): URL;
|
|
17
|
+
private callback;
|
|
18
|
+
private logout;
|
|
19
|
+
withAuthRequest<C>(handler: (req: NextRequest, ctx: C, session: AuditAuthTokenPayload) => Promise<Response>): (req: NextRequest, ctx: C) => Promise<Response>;
|
|
20
|
+
fetch(url: string, init?: RequestInit): Promise<Response>;
|
|
21
|
+
private refresh;
|
|
34
22
|
middleware(request: NextRequest): Promise<NextResponse<unknown>>;
|
|
35
23
|
getHandlers(): {
|
|
36
24
|
GET: (req: NextRequest, ctx: {
|
|
@@ -38,7 +26,7 @@ declare class AuditAuthNext {
|
|
|
38
26
|
auditauth: string[];
|
|
39
27
|
}>;
|
|
40
28
|
}) => Promise<Response>;
|
|
41
|
-
POST: (req:
|
|
29
|
+
POST: (req: NextRequest, ctx: {
|
|
42
30
|
params: Promise<{
|
|
43
31
|
auditauth: string[];
|
|
44
32
|
}>;
|
package/dist/sdk.js
CHANGED
|
@@ -1,14 +1,8 @@
|
|
|
1
1
|
'use server';
|
|
2
|
-
import { NextResponse } from
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
/* KEYS */
|
|
7
|
-
/* -------------------------------------------------------------------------- */
|
|
8
|
-
let cachedKey = null;
|
|
9
|
-
/* -------------------------------------------------------------------------- */
|
|
10
|
-
/* MAIN CLASS */
|
|
11
|
-
/* -------------------------------------------------------------------------- */
|
|
2
|
+
import { NextResponse } from 'next/server.js';
|
|
3
|
+
import { SETTINGS } from './settings.js';
|
|
4
|
+
import { buildAuthUrl, authorizeCode, revokeSession, buildPortalUrl, refreshTokens, sendMetrics, } from '@auditauth/core';
|
|
5
|
+
import { verifyRequest } from "@auditauth/node";
|
|
12
6
|
class AuditAuthNext {
|
|
13
7
|
constructor(config, cookies) {
|
|
14
8
|
if (!config.appId)
|
|
@@ -25,40 +19,22 @@ class AuditAuthNext {
|
|
|
25
19
|
this.config = config;
|
|
26
20
|
this.cookies = cookies;
|
|
27
21
|
}
|
|
28
|
-
/* ------------------------------------------------------------------------ */
|
|
29
|
-
/* AUTH PRIMITIVES */
|
|
30
|
-
/* ------------------------------------------------------------------------ */
|
|
31
|
-
async verifyAccessToken(token) {
|
|
32
|
-
try {
|
|
33
|
-
cachedKey =
|
|
34
|
-
cachedKey ||
|
|
35
|
-
await importSPKI(SETTINGS.jwt_public_key, 'RS256');
|
|
36
|
-
await jwtVerify(token, cachedKey, {
|
|
37
|
-
issuer: SETTINGS.jwt_issuer,
|
|
38
|
-
audience: this.config.appId,
|
|
39
|
-
});
|
|
40
|
-
return true;
|
|
41
|
-
}
|
|
42
|
-
catch {
|
|
43
|
-
return false;
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
22
|
getCookieTokens() {
|
|
47
23
|
return {
|
|
48
|
-
access: this.cookies.get(SETTINGS.
|
|
49
|
-
refresh: this.cookies.get(SETTINGS.
|
|
24
|
+
access: this.cookies.get(SETTINGS.storage_keys.access),
|
|
25
|
+
refresh: this.cookies.get(SETTINGS.storage_keys.refresh),
|
|
50
26
|
};
|
|
51
27
|
}
|
|
52
28
|
setCookieTokens(params) {
|
|
53
29
|
const isSecure = this.config.redirectUrl.includes('https');
|
|
54
|
-
this.cookies.set(SETTINGS.
|
|
30
|
+
this.cookies.set(SETTINGS.storage_keys.access, params.access_token, {
|
|
55
31
|
httpOnly: true,
|
|
56
32
|
sameSite: 'lax',
|
|
57
33
|
secure: isSecure,
|
|
58
34
|
path: '/',
|
|
59
35
|
maxAge: params.access_expires_seconds - 60,
|
|
60
36
|
});
|
|
61
|
-
this.cookies.set(SETTINGS.
|
|
37
|
+
this.cookies.set(SETTINGS.storage_keys.refresh, params.refresh_token, {
|
|
62
38
|
httpOnly: true,
|
|
63
39
|
sameSite: 'lax',
|
|
64
40
|
secure: isSecure,
|
|
@@ -66,135 +42,91 @@ class AuditAuthNext {
|
|
|
66
42
|
maxAge: params.refresh_expires_seconds - 60,
|
|
67
43
|
});
|
|
68
44
|
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
45
|
+
pushMetric(payload) {
|
|
46
|
+
const session_id = this.cookies.get(SETTINGS.storage_keys.session_id);
|
|
47
|
+
queueMicrotask(() => {
|
|
48
|
+
fetch(`${this.config.baseUrl}${SETTINGS.bff.paths.metrics}`, {
|
|
49
|
+
method: 'POST',
|
|
50
|
+
headers: { 'Content-Type': 'application/json' },
|
|
51
|
+
body: JSON.stringify({ ...payload, session_id }),
|
|
52
|
+
}).catch(() => { });
|
|
53
|
+
});
|
|
54
|
+
}
|
|
72
55
|
getSession() {
|
|
73
|
-
return JSON.parse(this.cookies.get(SETTINGS.
|
|
56
|
+
return JSON.parse(this.cookies.get(SETTINGS.storage_keys.session) || '{}')?.user || null;
|
|
74
57
|
}
|
|
75
58
|
hasSession() {
|
|
76
|
-
return !!this.cookies.get(SETTINGS.
|
|
59
|
+
return !!this.cookies.get(SETTINGS.storage_keys.session);
|
|
77
60
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
}
|
|
89
|
-
const { code, redirectUrl } = await response.json();
|
|
90
|
-
const url = new URL(redirectUrl);
|
|
91
|
-
url.searchParams.set('code', code);
|
|
61
|
+
getLoginUrl() {
|
|
62
|
+
const url = new URL(SETTINGS.bff.paths.login, this.config.baseUrl);
|
|
63
|
+
return url;
|
|
64
|
+
}
|
|
65
|
+
getLogoutUrl() {
|
|
66
|
+
const url = new URL(SETTINGS.bff.paths.logout, this.config.baseUrl);
|
|
67
|
+
return url;
|
|
68
|
+
}
|
|
69
|
+
getPortalUrl() {
|
|
70
|
+
const url = new URL(SETTINGS.bff.paths.portal, this.config.baseUrl);
|
|
92
71
|
return url;
|
|
93
72
|
}
|
|
94
73
|
async callback(request) {
|
|
95
74
|
const code = new URL(request.url).searchParams.get('code');
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
75
|
+
try {
|
|
76
|
+
const { data } = await authorizeCode({ code, client_type: 'server' });
|
|
77
|
+
const session = {
|
|
78
|
+
user: data.user,
|
|
100
79
|
};
|
|
80
|
+
const isSecure = this.config.redirectUrl.includes('http');
|
|
81
|
+
this.cookies.set(SETTINGS.storage_keys.session, JSON.stringify(session), {
|
|
82
|
+
httpOnly: true,
|
|
83
|
+
sameSite: 'lax',
|
|
84
|
+
secure: isSecure,
|
|
85
|
+
path: '/',
|
|
86
|
+
maxAge: data.refresh_expires_seconds - 60,
|
|
87
|
+
});
|
|
88
|
+
this.setCookieTokens({
|
|
89
|
+
access_token: data.access_token,
|
|
90
|
+
access_expires_seconds: data.access_expires_seconds,
|
|
91
|
+
refresh_token: data.refresh_token,
|
|
92
|
+
refresh_expires_seconds: data.refresh_expires_seconds,
|
|
93
|
+
});
|
|
94
|
+
return { ok: true, url: this.config.redirectUrl };
|
|
101
95
|
}
|
|
102
|
-
|
|
103
|
-
method: 'POST',
|
|
104
|
-
headers: { 'Content-Type': 'application/json' },
|
|
105
|
-
body: JSON.stringify({ code, client_type: 'server' }),
|
|
106
|
-
});
|
|
107
|
-
if (!response.ok) {
|
|
96
|
+
catch {
|
|
108
97
|
return {
|
|
109
98
|
ok: false,
|
|
110
|
-
url: `${SETTINGS.domains.client}/auth/invalid?reason=
|
|
99
|
+
url: `${SETTINGS.domains.client}/auth/invalid?reason=wrong_config`,
|
|
111
100
|
};
|
|
112
101
|
}
|
|
113
|
-
const result = await response.json();
|
|
114
|
-
const session = {
|
|
115
|
-
user: {
|
|
116
|
-
_id: result.user._id.toString(),
|
|
117
|
-
email: result.user.email,
|
|
118
|
-
avatar: result.user.avatar,
|
|
119
|
-
name: result.user.name,
|
|
120
|
-
},
|
|
121
|
-
};
|
|
122
|
-
const isSecure = this.config.redirectUrl.includes('http');
|
|
123
|
-
this.cookies.set(SETTINGS.cookies.session.name, JSON.stringify(session), {
|
|
124
|
-
httpOnly: true,
|
|
125
|
-
sameSite: 'lax',
|
|
126
|
-
secure: isSecure,
|
|
127
|
-
path: '/',
|
|
128
|
-
maxAge: result.refresh_expires_seconds - 60,
|
|
129
|
-
});
|
|
130
|
-
this.setCookieTokens({
|
|
131
|
-
access_token: result.access_token,
|
|
132
|
-
access_expires_seconds: result.access_expires_seconds,
|
|
133
|
-
refresh_token: result.refresh_token,
|
|
134
|
-
refresh_expires_seconds: result.refresh_expires_seconds,
|
|
135
|
-
});
|
|
136
|
-
return { ok: true, url: this.config.redirectUrl };
|
|
137
102
|
}
|
|
138
103
|
async logout() {
|
|
139
104
|
const { access } = this.getCookieTokens();
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
}
|
|
146
|
-
this.cookies.remove(SETTINGS.cookies.access.name);
|
|
147
|
-
this.cookies.remove(SETTINGS.cookies.refresh.name);
|
|
148
|
-
this.cookies.remove(SETTINGS.cookies.session.name);
|
|
105
|
+
this.cookies.remove(SETTINGS.storage_keys.access);
|
|
106
|
+
this.cookies.remove(SETTINGS.storage_keys.refresh);
|
|
107
|
+
this.cookies.remove(SETTINGS.storage_keys.session);
|
|
108
|
+
if (!access)
|
|
109
|
+
return;
|
|
110
|
+
await revokeSession({ access_token: access }).catch(() => { });
|
|
149
111
|
}
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
return { ok: false, url: null, reason: 'fail' };
|
|
163
|
-
}
|
|
164
|
-
const body = await res.json();
|
|
165
|
-
return {
|
|
166
|
-
ok: true,
|
|
167
|
-
url: `${body.redirectUrl}?code=${body.code}&redirectUrl=${this.config.redirectUrl}`,
|
|
168
|
-
reason: null,
|
|
112
|
+
withAuthRequest(handler) {
|
|
113
|
+
return async (req, ctx) => {
|
|
114
|
+
try {
|
|
115
|
+
const session = await verifyRequest({
|
|
116
|
+
request: req,
|
|
117
|
+
appId: this.config.appId,
|
|
118
|
+
});
|
|
119
|
+
return handler(req, ctx, session);
|
|
120
|
+
}
|
|
121
|
+
catch (err) {
|
|
122
|
+
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
|
|
123
|
+
}
|
|
169
124
|
};
|
|
170
125
|
}
|
|
171
|
-
|
|
172
|
-
/* REFRESH FLOW */
|
|
173
|
-
/* ------------------------------------------------------------------------ */
|
|
174
|
-
async refreshRequest(refreshToken) {
|
|
175
|
-
try {
|
|
176
|
-
const response = await fetch(`${SETTINGS.domains.api}/auth/refresh`, {
|
|
177
|
-
method: 'POST',
|
|
178
|
-
headers: { 'Content-Type': 'application/json' },
|
|
179
|
-
body: JSON.stringify({
|
|
180
|
-
refresh_token: refreshToken,
|
|
181
|
-
client_type: 'server',
|
|
182
|
-
}),
|
|
183
|
-
});
|
|
184
|
-
if (!response.ok)
|
|
185
|
-
return null;
|
|
186
|
-
return response.json();
|
|
187
|
-
}
|
|
188
|
-
catch {
|
|
189
|
-
return null;
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
/* ------------------------------------------------------------------------ */
|
|
193
|
-
/* REQUEST WITH AUTO-REFRESH */
|
|
194
|
-
/* ------------------------------------------------------------------------ */
|
|
195
|
-
async request(url, init = {}) {
|
|
126
|
+
async fetch(url, init = {}) {
|
|
196
127
|
const { access, refresh } = this.getCookieTokens();
|
|
197
|
-
const
|
|
128
|
+
const finalUrl = url.startsWith('http') ? url : `${this.config.baseUrl}${url}`;
|
|
129
|
+
const doFetch = (token) => fetch(finalUrl, {
|
|
198
130
|
...init,
|
|
199
131
|
headers: {
|
|
200
132
|
...init.headers,
|
|
@@ -204,9 +136,12 @@ class AuditAuthNext {
|
|
|
204
136
|
const start = performance.now();
|
|
205
137
|
let res = await doFetch(access);
|
|
206
138
|
if (res.status === 401 && refresh) {
|
|
207
|
-
const
|
|
208
|
-
if (
|
|
209
|
-
res
|
|
139
|
+
const refreshData = await refreshTokens({ refresh_token: refresh, client_type: 'server' });
|
|
140
|
+
if (!refreshData) {
|
|
141
|
+
return res;
|
|
142
|
+
}
|
|
143
|
+
if (refreshData.access_token && refreshData.refresh_token) {
|
|
144
|
+
res = await doFetch(refreshData.access_token);
|
|
210
145
|
}
|
|
211
146
|
}
|
|
212
147
|
this.pushMetric({
|
|
@@ -222,54 +157,29 @@ class AuditAuthNext {
|
|
|
222
157
|
});
|
|
223
158
|
return res;
|
|
224
159
|
}
|
|
225
|
-
/* ------------------------------------------------------------------------ */
|
|
226
|
-
/* METRICS */
|
|
227
|
-
/* ------------------------------------------------------------------------ */
|
|
228
|
-
async metrics(payload) {
|
|
229
|
-
await fetch(`${SETTINGS.domains.api}/metrics`, {
|
|
230
|
-
method: 'POST',
|
|
231
|
-
headers: {
|
|
232
|
-
'Content-Type': 'application/json',
|
|
233
|
-
'x-auditauth-app': this.config.appId,
|
|
234
|
-
'x-auditauth-key': this.config.apiKey,
|
|
235
|
-
},
|
|
236
|
-
body: JSON.stringify({ ...payload }),
|
|
237
|
-
});
|
|
238
|
-
return new Response(null, { status: 204 });
|
|
239
|
-
}
|
|
240
|
-
pushMetric(payload) {
|
|
241
|
-
const session_id = this.cookies.get(SETTINGS.cookies.session_id.name);
|
|
242
|
-
queueMicrotask(() => {
|
|
243
|
-
fetch(`${this.config.baseUrl}${SETTINGS.bff.paths.metrics}`, {
|
|
244
|
-
method: 'POST',
|
|
245
|
-
headers: { 'Content-Type': 'application/json' },
|
|
246
|
-
body: JSON.stringify({ ...payload, session_id }),
|
|
247
|
-
}).catch(() => { });
|
|
248
|
-
});
|
|
249
|
-
}
|
|
250
|
-
/* ------------------------------------------------------------------------ */
|
|
251
|
-
/* METRICS */
|
|
252
|
-
/* ------------------------------------------------------------------------ */
|
|
253
160
|
async refresh() {
|
|
254
161
|
const { refresh } = this.getCookieTokens();
|
|
255
162
|
if (!refresh)
|
|
256
163
|
return { ok: false };
|
|
257
|
-
const result = await
|
|
164
|
+
const result = await refreshTokens({ refresh_token: refresh, client_type: 'server' });
|
|
258
165
|
if (!result)
|
|
259
166
|
return { ok: false };
|
|
260
|
-
|
|
167
|
+
const { access_token, refresh_token, access_expires_seconds, refresh_expires_seconds } = result;
|
|
168
|
+
this.setCookieTokens({
|
|
169
|
+
access_token,
|
|
170
|
+
access_expires_seconds,
|
|
171
|
+
refresh_token,
|
|
172
|
+
refresh_expires_seconds,
|
|
173
|
+
});
|
|
261
174
|
return { ok: true };
|
|
262
175
|
}
|
|
263
|
-
/* ------------------------------------------------------------------------ */
|
|
264
|
-
/* MIDDLEWARE */
|
|
265
|
-
/* ------------------------------------------------------------------------ */
|
|
266
176
|
async middleware(request) {
|
|
267
177
|
const { access, refresh } = this.getCookieTokens();
|
|
268
178
|
const url = request.nextUrl;
|
|
269
179
|
if (access && refresh) {
|
|
270
|
-
const sid = this.cookies.get(SETTINGS.
|
|
180
|
+
const sid = this.cookies.get(SETTINGS.storage_keys.session_id);
|
|
271
181
|
if (!sid) {
|
|
272
|
-
this.cookies.set(SETTINGS.
|
|
182
|
+
this.cookies.set(SETTINGS.storage_keys.session_id, crypto.randomUUID(), {
|
|
273
183
|
httpOnly: true,
|
|
274
184
|
sameSite: 'lax',
|
|
275
185
|
secure: this.config.baseUrl.startsWith('https'),
|
|
@@ -287,15 +197,17 @@ class AuditAuthNext {
|
|
|
287
197
|
});
|
|
288
198
|
return NextResponse.next();
|
|
289
199
|
}
|
|
290
|
-
if (!refresh)
|
|
200
|
+
if (!refresh) {
|
|
201
|
+
if (request.method !== 'GET') {
|
|
202
|
+
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
|
|
203
|
+
}
|
|
291
204
|
return NextResponse.redirect(new URL(SETTINGS.bff.paths.login, request.url));
|
|
292
|
-
|
|
205
|
+
}
|
|
206
|
+
if (refresh && !access) {
|
|
293
207
|
return NextResponse.redirect(new URL(`${SETTINGS.bff.paths.refresh}?redirectUrl=${url}`, request.url));
|
|
208
|
+
}
|
|
294
209
|
return NextResponse.next();
|
|
295
210
|
}
|
|
296
|
-
/* ------------------------------------------------------------------------ */
|
|
297
|
-
/* BFF HANDLERS */
|
|
298
|
-
/* ------------------------------------------------------------------------ */
|
|
299
211
|
getHandlers() {
|
|
300
212
|
return {
|
|
301
213
|
GET: async (req, ctx) => {
|
|
@@ -304,7 +216,7 @@ class AuditAuthNext {
|
|
|
304
216
|
switch (action) {
|
|
305
217
|
case 'login':
|
|
306
218
|
{
|
|
307
|
-
const url = await this.
|
|
219
|
+
const url = await buildAuthUrl({ apiKey: this.config.apiKey, redirectUrl: `${this.config.baseUrl}/api/auditauth/callback` });
|
|
308
220
|
return NextResponse.redirect(url);
|
|
309
221
|
}
|
|
310
222
|
;
|
|
@@ -313,7 +225,7 @@ class AuditAuthNext {
|
|
|
313
225
|
const { ok } = await this.refresh();
|
|
314
226
|
if (ok)
|
|
315
227
|
return NextResponse.redirect(redirectUrl || this.config.redirectUrl);
|
|
316
|
-
const url = await this.
|
|
228
|
+
const url = await buildAuthUrl({ apiKey: this.config.apiKey, redirectUrl: `${this.config.baseUrl}/api/auditauth/callback` });
|
|
317
229
|
return NextResponse.redirect(url);
|
|
318
230
|
}
|
|
319
231
|
;
|
|
@@ -331,10 +243,16 @@ class AuditAuthNext {
|
|
|
331
243
|
;
|
|
332
244
|
case 'portal':
|
|
333
245
|
{
|
|
334
|
-
const {
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
246
|
+
const { access } = this.getCookieTokens();
|
|
247
|
+
try {
|
|
248
|
+
if (!access)
|
|
249
|
+
throw new Error('Not auth token');
|
|
250
|
+
const url = await buildPortalUrl({ access_token: access, redirectUrl: this.config.redirectUrl });
|
|
251
|
+
return NextResponse.redirect(url);
|
|
252
|
+
}
|
|
253
|
+
catch (err) {
|
|
254
|
+
return NextResponse.redirect(`${SETTINGS.domains.client}/auth/invalid`);
|
|
255
|
+
}
|
|
338
256
|
}
|
|
339
257
|
;
|
|
340
258
|
case 'session':
|
|
@@ -354,10 +272,34 @@ class AuditAuthNext {
|
|
|
354
272
|
},
|
|
355
273
|
POST: async (req, ctx) => {
|
|
356
274
|
const action = (await ctx.params).auditauth[0];
|
|
357
|
-
|
|
358
|
-
|
|
275
|
+
switch (action) {
|
|
276
|
+
case 'metrics':
|
|
277
|
+
{
|
|
278
|
+
const payload = await req.json();
|
|
279
|
+
await sendMetrics({
|
|
280
|
+
payload,
|
|
281
|
+
appId: this.config.appId,
|
|
282
|
+
apiKey: this.config.apiKey,
|
|
283
|
+
});
|
|
284
|
+
return new Response(null, { status: 204 });
|
|
285
|
+
}
|
|
286
|
+
;
|
|
287
|
+
case 'refresh':
|
|
288
|
+
{
|
|
289
|
+
const redirectUrl = req.nextUrl.searchParams.get('redirectUrl');
|
|
290
|
+
const { ok } = await this.refresh();
|
|
291
|
+
if (ok)
|
|
292
|
+
return NextResponse.redirect(redirectUrl || this.config.redirectUrl);
|
|
293
|
+
return new Response('Session expired', { status: 401 });
|
|
294
|
+
}
|
|
295
|
+
;
|
|
296
|
+
default:
|
|
297
|
+
{
|
|
298
|
+
return new Response('not found', { status: 404 });
|
|
299
|
+
}
|
|
300
|
+
;
|
|
359
301
|
}
|
|
360
|
-
|
|
302
|
+
;
|
|
361
303
|
},
|
|
362
304
|
};
|
|
363
305
|
}
|
package/dist/settings.d.ts
CHANGED
|
@@ -1,10 +1,4 @@
|
|
|
1
1
|
declare const SETTINGS: {
|
|
2
|
-
readonly jwt_public_key: "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAs2EYs4Q9OyjNuAEPqb4j\nIzc52JdfVcNvEbG43Xp8B2kI9QxwRyX7rtFSwKowj3W1BlCLaTIMK3TafWOf9QwH\nfemuL9Ni37PFcGptzpyuoCYYA650EuD82PENcO49lsObvty2cuXxQszbPPvAecm4\nJ/XG70td/W1UwbjAJcdmp8ktZGYR0JXM37hYA9Xq/aKwu7d0FTL6WdKTvt3L5VxL\nF6WNyLs65ZSbu+j8UEkwmoJ9h9Y0mLQmFtmkoh/HWOFyFDnBNiJX0vRb++RhJw6w\ncrSbqpbTu7z4vIep5lgSOut39P273SVTQZ3cGQIS+605Ur5wjkkSzzaJV1QLBBR9\nAQIDAQAB\n-----END PUBLIC KEY-----\n";
|
|
3
|
-
readonly jwt_issuer: "https://api.auditauth.com";
|
|
4
|
-
readonly domains: {
|
|
5
|
-
readonly api: "https://api.auditauth.com/v1";
|
|
6
|
-
readonly client: "https://auditauth.com";
|
|
7
|
-
};
|
|
8
2
|
readonly bff: {
|
|
9
3
|
readonly paths: {
|
|
10
4
|
readonly callback: "/api/auditauth/callback";
|
|
@@ -14,21 +8,24 @@ declare const SETTINGS: {
|
|
|
14
8
|
readonly portal: "/api/auditauth/portal";
|
|
15
9
|
readonly session: "/api/auditauth/session";
|
|
16
10
|
readonly refresh: "/api/auditauth/refresh";
|
|
11
|
+
readonly proxy: "/api/auditauth/proxy";
|
|
17
12
|
};
|
|
18
13
|
};
|
|
19
|
-
readonly
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
readonly
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
readonly
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
readonly
|
|
30
|
-
|
|
31
|
-
|
|
14
|
+
readonly jwt_public_key: "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAs2EYs4Q9OyjNuAEPqb4j\nIzc52JdfVcNvEbG43Xp8B2kI9QxwRyX7rtFSwKowj3W1BlCLaTIMK3TafWOf9QwH\nfemuL9Ni37PFcGptzpyuoCYYA650EuD82PENcO49lsObvty2cuXxQszbPPvAecm4\nJ/XG70td/W1UwbjAJcdmp8ktZGYR0JXM37hYA9Xq/aKwu7d0FTL6WdKTvt3L5VxL\nF6WNyLs65ZSbu+j8UEkwmoJ9h9Y0mLQmFtmkoh/HWOFyFDnBNiJX0vRb++RhJw6w\ncrSbqpbTu7z4vIep5lgSOut39P273SVTQZ3cGQIS+605Ur5wjkkSzzaJV1QLBBR9\nAQIDAQAB\n-----END PUBLIC KEY-----\n";
|
|
15
|
+
readonly jwt_issuer: "https://api.auditauth.com";
|
|
16
|
+
readonly domains: {
|
|
17
|
+
readonly api: "https://api.auditauth.com/v1";
|
|
18
|
+
readonly client: "https://auditauth.com";
|
|
19
|
+
} | {
|
|
20
|
+
readonly api: "http://localhost:4000/v1";
|
|
21
|
+
readonly client: "http://localhost:3000";
|
|
22
|
+
};
|
|
23
|
+
readonly storage_keys: {
|
|
24
|
+
readonly access: "auditauth_access";
|
|
25
|
+
readonly session: "auditauth_session";
|
|
26
|
+
readonly refresh: "auditauth_refresh";
|
|
27
|
+
readonly session_id: "auditauth_sid";
|
|
28
|
+
readonly sync: "__auditauth_sync__";
|
|
32
29
|
};
|
|
33
30
|
};
|
|
34
31
|
export { SETTINGS };
|
package/dist/settings.js
CHANGED
|
@@ -1,12 +1,6 @@
|
|
|
1
|
+
import { CORE_SETTINGS } from '@auditauth/core';
|
|
1
2
|
const SETTINGS = {
|
|
2
|
-
|
|
3
|
-
jwt_issuer: "https://api.auditauth.com",
|
|
4
|
-
domains: {
|
|
5
|
-
api: 'https://api.auditauth.com/v1',
|
|
6
|
-
client: 'https://auditauth.com',
|
|
7
|
-
// api: 'http://localhost:4000/v1',
|
|
8
|
-
// client: 'http://localhost:3000',
|
|
9
|
-
},
|
|
3
|
+
...CORE_SETTINGS,
|
|
10
4
|
bff: {
|
|
11
5
|
paths: {
|
|
12
6
|
callback: '/api/auditauth/callback',
|
|
@@ -16,21 +10,8 @@ const SETTINGS = {
|
|
|
16
10
|
portal: '/api/auditauth/portal',
|
|
17
11
|
session: '/api/auditauth/session',
|
|
18
12
|
refresh: '/api/auditauth/refresh',
|
|
13
|
+
proxy: '/api/auditauth/proxy',
|
|
19
14
|
}
|
|
20
15
|
},
|
|
21
|
-
cookies: {
|
|
22
|
-
access: {
|
|
23
|
-
name: 'auditauth_access',
|
|
24
|
-
},
|
|
25
|
-
session: {
|
|
26
|
-
name: 'auditauth_session',
|
|
27
|
-
},
|
|
28
|
-
refresh: {
|
|
29
|
-
name: 'auditauth_refresh',
|
|
30
|
-
},
|
|
31
|
-
session_id: {
|
|
32
|
-
name: 'auditauth_sid',
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
16
|
};
|
|
36
17
|
export { SETTINGS };
|
package/dist/types.d.ts
CHANGED
|
@@ -1,23 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
apiKey: string;
|
|
3
|
-
redirectUrl: string;
|
|
4
|
-
baseUrl: string;
|
|
5
|
-
appId: string;
|
|
6
|
-
};
|
|
7
|
-
type CredentialResponse = {
|
|
8
|
-
access_token: string;
|
|
9
|
-
access_expires_seconds: number;
|
|
10
|
-
refresh_token: string;
|
|
11
|
-
refresh_expires_seconds: number;
|
|
12
|
-
};
|
|
13
|
-
type SessionUser = {
|
|
14
|
-
_id: string;
|
|
15
|
-
name: string;
|
|
16
|
-
email: string;
|
|
17
|
-
avatar: {
|
|
18
|
-
url: string | null;
|
|
19
|
-
};
|
|
20
|
-
};
|
|
1
|
+
import { SessionUser } from "@auditauth/core";
|
|
21
2
|
type Session = {
|
|
22
3
|
user: SessionUser;
|
|
23
4
|
};
|
|
@@ -28,28 +9,9 @@ type CookieOptions = {
|
|
|
28
9
|
path?: string;
|
|
29
10
|
maxAge?: number;
|
|
30
11
|
};
|
|
31
|
-
type RequestMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
|
|
32
|
-
type Metric = {
|
|
33
|
-
event_type: 'request';
|
|
34
|
-
runtime: 'browser' | 'server';
|
|
35
|
-
target: {
|
|
36
|
-
type: 'api';
|
|
37
|
-
method: RequestMethod;
|
|
38
|
-
path: string;
|
|
39
|
-
status: number;
|
|
40
|
-
duration_ms: number;
|
|
41
|
-
};
|
|
42
|
-
} | {
|
|
43
|
-
event_type: 'navigation';
|
|
44
|
-
runtime: 'browser' | 'server';
|
|
45
|
-
target: {
|
|
46
|
-
type: 'page';
|
|
47
|
-
path: string;
|
|
48
|
-
};
|
|
49
|
-
};
|
|
50
12
|
type CookieAdapter = {
|
|
51
13
|
get: (name: string) => string | undefined;
|
|
52
14
|
set: (name: string, value: string, options?: CookieOptions) => void;
|
|
53
15
|
remove: (name: string) => void;
|
|
54
16
|
};
|
|
55
|
-
export type {
|
|
17
|
+
export type { Session, CookieOptions, CookieAdapter, };
|
package/package.json
CHANGED
|
@@ -1,15 +1,36 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@auditauth/next",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.2.0-beta.2",
|
|
4
|
+
"description": "AuditAuth NextJS SDK",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Nimibyte",
|
|
7
|
+
"engines": {
|
|
8
|
+
"node": ">=18.18.0"
|
|
9
|
+
},
|
|
10
|
+
"repository": {
|
|
11
|
+
"type": "git",
|
|
12
|
+
"url": "https://github.com/nimibyte/auditauth-sdk.git"
|
|
13
|
+
},
|
|
14
|
+
"homepage": "https://docs.auditauth.com",
|
|
15
|
+
"bugs": {
|
|
16
|
+
"url": "https://github.com/nimibyte/auditauth-sdk/issues"
|
|
17
|
+
},
|
|
18
|
+
"keywords": [
|
|
19
|
+
"authentication",
|
|
20
|
+
"auth",
|
|
21
|
+
"oauth",
|
|
22
|
+
"identity",
|
|
23
|
+
"jwt",
|
|
24
|
+
"security",
|
|
25
|
+
"auditauth"
|
|
26
|
+
],
|
|
7
27
|
"type": "module",
|
|
8
28
|
"main": "dist/index.js",
|
|
9
29
|
"types": "dist/index.d.ts",
|
|
10
30
|
"files": [
|
|
11
31
|
"dist"
|
|
12
32
|
],
|
|
33
|
+
"sideEffects": false,
|
|
13
34
|
"exports": {
|
|
14
35
|
".": {
|
|
15
36
|
"types": "./dist/index.d.ts",
|
|
@@ -18,8 +39,8 @@
|
|
|
18
39
|
},
|
|
19
40
|
"scripts": {
|
|
20
41
|
"build": "tsc -p tsconfig.build.json",
|
|
21
|
-
"
|
|
22
|
-
"
|
|
42
|
+
"dev": "tsc -p tsconfig.build.json --watch",
|
|
43
|
+
"clean": "rm -rf dist"
|
|
23
44
|
},
|
|
24
45
|
"peerDependencies": {
|
|
25
46
|
"next": ">=13",
|
|
@@ -27,12 +48,13 @@
|
|
|
27
48
|
"react-dom": ">=18"
|
|
28
49
|
},
|
|
29
50
|
"dependencies": {
|
|
30
|
-
"
|
|
51
|
+
"@auditauth/core": "^0.2.0-beta.2",
|
|
52
|
+
"@auditauth/node": "^0.2.0-beta.2"
|
|
31
53
|
},
|
|
32
54
|
"devDependencies": {
|
|
33
|
-
"
|
|
55
|
+
"typescript": "^5.9.0",
|
|
56
|
+
"@types/node": "^20",
|
|
34
57
|
"@types/react": "^19.2.8",
|
|
35
|
-
"@types/react-dom": "^19.2.3"
|
|
36
|
-
"typescript": "^5.9.3"
|
|
58
|
+
"@types/react-dom": "^19.2.3"
|
|
37
59
|
}
|
|
38
60
|
}
|
package/LICENSE
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2026 Nimibyte
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|