Skip to content

Commit 156e54f

Browse files
authored
Merge pull request #6 from macropygia/feature/restructure-dirs
Fix Lowdb adapter
2 parents a0fccf3 + 10a697b commit 156e54f

File tree

85 files changed

+1865
-1428
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

85 files changed

+1865
-1428
lines changed

.gitignore

+3-4
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
.env
2+
.temp
23
docs
3-
index.js
4-
index.d.ts
5-
dist
6-
tsconfig.tsbuildinfo
4+
*.js
5+
*.d.ts
76
.vscode/settings.json
87
node_modules

README.ja.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -241,10 +241,10 @@ bun add lowdb
241241
import { LowdbAdapter } from 'elysia-openid-client/dataAdapters/LowdbAdapter';
242242

243243
// インメモリーモード
244-
const memoryAdapter = new LowdbAdapter();
244+
const memoryAdapter = await LowdbAdapter.create();
245245

246246
// 永続化モード
247-
const fileAdapter = new LowdbAdapter({
247+
const fileAdapter = await LowdbAdapter.create({
248248
filename: "sessions.json",
249249
})
250250
```

README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -241,10 +241,10 @@ bun add lowdb
241241
import { LowdbAdapter } from 'elysia-openid-client/dataAdapters/LowdbAdapter';
242242

243243
// In-memory
244-
const memoryAdapter = new LowdbAdapter();
244+
const memoryAdapter = await LowdbAdapter.create();
245245

246246
// Persistence to file
247-
const fileAdapter = new LowdbAdapter({
247+
const fileAdapter = await LowdbAdapter.create({
248248
filename: "sessions.json",
249249
})
250250
```

__test__/compose.yml __mock__/compose.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
services:
22
redis:
3-
image: redis:7
3+
image: redis:7-alpine
44
container_name: elysia-openid-client-redis
55
hostname: redis-server
66
ports:

__mock__/const.ts

+220
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,220 @@
1+
import { mock } from "bun:test";
2+
import type { OidcClient } from "@/core/OidcClient";
3+
import { defaultCookieSettings, defaultSettings } from "@/core/const";
4+
import { consoleLogger } from "@/loggers/consoleLogger";
5+
import type {
6+
OIDCClientActiveSession,
7+
OIDCClientOptions,
8+
OIDCClientSession,
9+
} from "@/types";
10+
import type { Cookie } from "elysia";
11+
import type { IdTokenClaims } from "openid-client";
12+
13+
export type DeepPartial<T> = T extends object
14+
? { [P in keyof T]?: DeepPartial<T[P]> }
15+
: T;
16+
17+
export const sqliteMockFile = "__mock__/mock.sqlite";
18+
export const sqliteTempFile = "__mock__/temp.sqlite";
19+
export const lokiMockFile = "__mock__/mock.db";
20+
export const lokiTempFile = "__mock__/temp.db";
21+
export const lowMockFile = "__mock__/mock.json";
22+
export const lowTempFile = "__mock__/temp.json";
23+
export const redisPort = 6379;
24+
export const redisHost = "localhost";
25+
export const rpPort = 57828;
26+
export const opPort = 57829;
27+
28+
export const logger = consoleLogger();
29+
30+
export const mockLogger = {
31+
silent: mock(),
32+
trace: mock(),
33+
debug: mock(),
34+
info: mock(),
35+
warn: mock(),
36+
error: mock(),
37+
fatal: mock(),
38+
};
39+
40+
export const mockBaseOptions = {
41+
baseUrl: `http://localhost:${rpPort}`,
42+
issuerUrl: `http://localhost:${opPort}`,
43+
clientMetadata: {
44+
client_id: "mock-client-id",
45+
client_secret: "mock-client-secret",
46+
},
47+
authParams: {},
48+
settings: defaultSettings,
49+
cookieSettings: {
50+
...defaultCookieSettings,
51+
secure: false,
52+
},
53+
} as OIDCClientOptions;
54+
55+
export const mockIdToken =
56+
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJtb2NrLXN1YiIsIm5vbmNlIjoibW9jay1ub25jZSIsImF1ZCI6Im1vY2stYXVkIiwiaWF0Ijo1MDAwMDAwMDAwLCJleHAiOjUwMDAwMDAwMDAsImlzcyI6Imh0dHBzOi8vb3AuZXhhbXBsZS5jb20ifQ.SyVdKzxYNl0ZsjZvJ9gZyOzPDEE9Q0_bI2l_j5B8fSw";
57+
58+
export const mockIdTokenExpired =
59+
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJtb2NrLXN1YiIsIm5vbmNlIjoibW9jay1ub25jZSIsImF1ZCI6Im1vY2stYXVkIiwiaWF0IjoxNzA0MDY3MjAwLCJleHAiOjE3MDQwNjcyMDAsImlzcyI6Imh0dHBzOi8vb3AuZXhhbXBsZS5jb20ifQ.JrNwu4_ji3cnoCDd_wxhRVbc25D1Y2io6n7VKDd5pLc";
60+
61+
export const mockIdTokenClaims = {
62+
aud: "mock-aud",
63+
exp: 5000000000,
64+
iat: 5000000000,
65+
iss: "https://op.example.com",
66+
nonce: "mock-nonce",
67+
sub: "mock-sub",
68+
};
69+
70+
export const mockIdTokenExpiredClaims = {
71+
aud: "mock-aud",
72+
exp: 1704067200,
73+
iat: 1704067200,
74+
iss: "https://op.example.com",
75+
nonce: "mock-nonce",
76+
sub: "mock-sub",
77+
};
78+
79+
export const mockLoginSession: OIDCClientSession = {
80+
sessionId: "mock-session-id",
81+
codeVerifier: "mock-code-verifier",
82+
state: "mock-state",
83+
nonce: "mock-nonce",
84+
sessionExpiresAt: 5000000000000,
85+
};
86+
87+
export const mockActiveSession: OIDCClientActiveSession = {
88+
sessionId: "mock-session-id",
89+
idToken: "mock-id-token",
90+
accessToken: "mock-access-token",
91+
refreshToken: "mock-refresh-token",
92+
sessionExpiresAt: 5000000000000,
93+
};
94+
95+
export const mockActiveSessionWithoutRefreshToken: OIDCClientActiveSession = {
96+
sessionId: "mock-session-id",
97+
idToken: "mock-id-token",
98+
accessToken: "mock-access-token",
99+
sessionExpiresAt: 5000000000000,
100+
};
101+
102+
export const mockActiveSessionWithRealIdToken: OIDCClientActiveSession = {
103+
sessionId: "mock-session-id",
104+
idToken: mockIdToken,
105+
accessToken: "mock-access-token",
106+
refreshToken: "mock-refresh-token",
107+
sessionExpiresAt: 5000000000000,
108+
};
109+
110+
export const mockActiveSessionWithRealIdTokenExpired: OIDCClientActiveSession =
111+
{
112+
sessionId: "mock-session-id",
113+
idToken: mockIdTokenExpired,
114+
accessToken: "mock-access-token",
115+
refreshToken: "mock-refresh-token",
116+
sessionExpiresAt: 5000000000000,
117+
};
118+
119+
export const mockPostInit = (sid?: string): RequestInit => ({
120+
method: "POST",
121+
headers: {
122+
Cookie: `${defaultCookieSettings.sessionIdName}=${sid || "mock-sid"}`,
123+
},
124+
});
125+
126+
export const mockGetInit = (sid?: string): RequestInit => ({
127+
headers: {
128+
Cookie: `${defaultCookieSettings.sessionIdName}=${sid || "mock-sid"}`,
129+
},
130+
});
131+
132+
export const mockClaims = {
133+
exp: 5000000000000 / 1000,
134+
iss: `http://localhost:${opPort}`,
135+
sub: "mock-sub",
136+
} as IdTokenClaims;
137+
138+
export const mockStatus = {
139+
sessionExpiresAt: mockActiveSession.sessionExpiresAt,
140+
hasRefreshToken: !!mockActiveSession.refreshToken,
141+
isExpired: mockClaims.exp * 1000 < Date.now(),
142+
expiresAt: mockClaims.exp * 1000,
143+
issuerUrl: mockClaims.iss,
144+
sub: mockClaims.sub,
145+
};
146+
147+
export const mockBaseClient = {
148+
...mockBaseOptions,
149+
create: mock(),
150+
initialize: mock(),
151+
validateOptions: mock(),
152+
createSession: mock(),
153+
updateSession: mock(),
154+
fetchSession: mock(),
155+
deleteSession: mock(),
156+
getSessionIdCookieType: mock(),
157+
getCookieDefinition: mock(),
158+
getAuthHook: mock(),
159+
getEndpoints: mock(),
160+
logger: mockLogger,
161+
initialized: true,
162+
client: {},
163+
sessions: mock(),
164+
} as DeepPartial<OidcClient> as OidcClient;
165+
166+
export const mockCookie = {
167+
[defaultCookieSettings.sessionIdName]: {
168+
value: mockActiveSession.sessionId,
169+
remove: mock(),
170+
update: mock(),
171+
},
172+
} as unknown as Record<string, Cookie<string>>;
173+
174+
/**
175+
* Clear calls/instances
176+
*/
177+
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
178+
export const mockClearRecursively = (mockObj: any) => {
179+
if (typeof mockObj !== "object") {
180+
return;
181+
}
182+
for (const [_name, maybeMethod] of Object.entries(mockObj)) {
183+
if (!maybeMethod) {
184+
continue;
185+
}
186+
if (
187+
typeof maybeMethod === "function" &&
188+
"mockClear" in maybeMethod &&
189+
typeof maybeMethod.mockClear === "function"
190+
) {
191+
maybeMethod.mockClear();
192+
} else if (typeof maybeMethod === "object") {
193+
mockClearRecursively(maybeMethod);
194+
}
195+
}
196+
};
197+
198+
/**
199+
* Reset all mocks to `mock()`
200+
*/
201+
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
202+
export const mockResetRecursively = (mockObj: any) => {
203+
if (typeof mockObj !== "object") {
204+
return;
205+
}
206+
for (const [_name, maybeMethod] of Object.entries(mockObj)) {
207+
if (!maybeMethod) {
208+
continue;
209+
}
210+
if (
211+
typeof maybeMethod === "function" &&
212+
"mockReset" in maybeMethod &&
213+
typeof maybeMethod.mockReset === "function"
214+
) {
215+
maybeMethod.mockReset();
216+
} else if (typeof maybeMethod === "object") {
217+
mockResetRecursively(maybeMethod);
218+
}
219+
}
220+
};

__mock__/issuerMetadata.ts

+103
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
import { opPort } from "./const";
2+
3+
export const mockIssuerMetadata = {
4+
issuer: `http://localhost:${opPort}`,
5+
authorization_endpoint: `http://localhost:${opPort}/oauth2/authorize`,
6+
token_endpoint: `http://localhost:${opPort}/oauth2/token`,
7+
userinfo_endpoint: `http://localhost:${opPort}/oauth2/userinfo`,
8+
registration_endpoint: `http://localhost:${opPort}/oauth2/clients`,
9+
jwks_uri: `http://localhost:${opPort}/oauth2/keys`,
10+
response_types_supported: ["code"],
11+
response_modes_supported: ["query"],
12+
grant_types_supported: ["authorization_code", "refresh_token"],
13+
subject_types_supported: ["public"],
14+
id_token_signing_alg_values_supported: ["RS256"],
15+
scopes_supported: [
16+
"openid",
17+
"email",
18+
"profile",
19+
"address",
20+
"phone",
21+
"offline_access",
22+
"groups",
23+
],
24+
token_endpoint_auth_methods_supported: [
25+
// "client_secret_basic",
26+
"client_secret_post",
27+
// "client_secret_jwt",
28+
// "private_key_jwt",
29+
"none",
30+
],
31+
claims_supported: [
32+
"iss",
33+
"ver",
34+
"sub",
35+
"aud",
36+
"iat",
37+
"exp",
38+
"jti",
39+
"auth_time",
40+
"amr",
41+
"idp",
42+
"nonce",
43+
"name",
44+
"nickname",
45+
"preferred_username",
46+
"given_name",
47+
"middle_name",
48+
"family_name",
49+
"email",
50+
"email_verified",
51+
"profile",
52+
"zoneinfo",
53+
"locale",
54+
"address",
55+
"phone_number",
56+
"picture",
57+
"website",
58+
"gender",
59+
"birthdate",
60+
"updated_at",
61+
"at_hash",
62+
"c_hash",
63+
],
64+
code_challenge_methods_supported: ["S256"],
65+
introspection_endpoint: `http://localhost:${opPort}/oauth2/introspect`,
66+
introspection_endpoint_auth_methods_supported: [
67+
"client_secret_basic",
68+
"client_secret_post",
69+
"client_secret_jwt",
70+
"private_key_jwt",
71+
"none",
72+
],
73+
revocation_endpoint: `http://localhost:${opPort}/oauth2/revoke`,
74+
revocation_endpoint_auth_methods_supported: [
75+
"client_secret_basic",
76+
"client_secret_post",
77+
"client_secret_jwt",
78+
"private_key_jwt",
79+
"none",
80+
],
81+
end_session_endpoint: `http://localhost:${opPort}/oauth2/logout`,
82+
request_parameter_supported: true,
83+
request_object_signing_alg_values_supported: [
84+
"HS256",
85+
"HS384",
86+
"HS512",
87+
"RS256",
88+
"RS384",
89+
"RS512",
90+
"ES256",
91+
"ES384",
92+
"ES512",
93+
],
94+
device_authorization_endpoint: `http://localhost:${opPort}/oauth2/device/authorize`,
95+
dpop_signing_alg_values_supported: [
96+
"RS256",
97+
"RS384",
98+
"RS512",
99+
"ES256",
100+
"ES384",
101+
"ES512",
102+
],
103+
};

__test__/test.db __mock__/mock.db

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"filename":"__test__/test.db","collections":[{"name":"sessions","data":[{"sessionId":"mock-session-id","idToken":"mock-id-token","accessToken":"mock-access-token","refreshToken":"mock-refresh-token","sessionExpiresAt":5000000000000,"meta":{"revision":0,"created":1713117345790,"version":0},"$loki":1}],"idIndex":[1],"binaryIndices":{"sessionId":{"name":"sessionId","dirty":false,"values":[0]},"sessionExpiresAt":{"name":"sessionExpiresAt","dirty":false,"values":[0]}},"constraints":null,"uniqueNames":["sessionId"],"transforms":{},"objType":"sessions","dirty":false,"cachedIndex":null,"cachedBinaryIndex":null,"cachedData":null,"adaptiveBinaryIndices":true,"transactional":false,"cloneObjects":false,"cloneMethod":"parse-stringify","asyncListeners":false,"disableMeta":false,"disableChangesApi":true,"disableDeltaChangesApi":true,"autoupdate":false,"serializableIndices":true,"disableFreeze":true,"ttl":null,"maxId":1,"DynamicViews":[],"events":{"insert":[],"update":[],"pre-insert":[],"pre-update":[],"close":[],"flushbuffer":[],"error":[],"delete":[null],"warning":[null]},"changes":[],"dirtyIds":[]}],"databaseVersion":1.5,"engineVersion":1.5,"autosave":true,"autosaveInterval":500,"autosaveHandle":null,"throttledSaves":true,"options":{"autoload":true,"autosave":true,"autosaveInterval":500,"serializationMethod":"normal","destructureDelimiter":"$<\n","recursiveWait":true,"recursiveWaitLimit":false,"recursiveWaitLimitDuration":2000,"started":1713117345691},"persistenceMethod":"fs","persistenceAdapter":null,"verbose":false,"events":{"init":[null],"loaded":[],"flushChanges":[],"close":[],"changes":[],"warning":[]},"ENV":"NODEJS"}
1+
{"filename":"__mock__/mock.db","collections":[{"name":"sessions","data":[{"sessionId":"mock-session-id","idToken":"mock-id-token","accessToken":"mock-access-token","refreshToken":"mock-refresh-token","sessionExpiresAt":5000000000000,"meta":{"revision":0,"created":1713731229754,"version":0},"$loki":1}],"idIndex":[1],"binaryIndices":{"sessionId":{"name":"sessionId","dirty":false,"values":[0]},"sessionExpiresAt":{"name":"sessionExpiresAt","dirty":false,"values":[0]}},"constraints":null,"uniqueNames":["sessionId"],"transforms":{},"objType":"sessions","dirty":false,"cachedIndex":null,"cachedBinaryIndex":null,"cachedData":null,"adaptiveBinaryIndices":true,"transactional":false,"cloneObjects":false,"cloneMethod":"parse-stringify","asyncListeners":false,"disableMeta":false,"disableChangesApi":true,"disableDeltaChangesApi":true,"autoupdate":false,"serializableIndices":true,"disableFreeze":true,"ttl":null,"maxId":1,"DynamicViews":[],"events":{"insert":[],"update":[],"pre-insert":[],"pre-update":[],"close":[],"flushbuffer":[],"error":[],"delete":[null],"warning":[null]},"changes":[],"dirtyIds":[]}],"databaseVersion":1.5,"engineVersion":1.5,"autosave":true,"autosaveInterval":500,"autosaveHandle":null,"throttledSaves":true,"options":{"autoload":true,"autosave":true,"autosaveInterval":500,"serializationMethod":"normal","destructureDelimiter":"$<\n","recursiveWait":true,"recursiveWaitLimit":false,"recursiveWaitLimitDuration":2000,"started":1713731229652},"persistenceMethod":"fs","persistenceAdapter":null,"verbose":false,"events":{"init":[null],"loaded":[],"flushChanges":[],"close":[],"changes":[],"warning":[]},"ENV":"NODEJS"}

__mock__/mock.json

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
[
2+
{
3+
"sessionId": "mock-session-id",
4+
"idToken": "mock-id-token",
5+
"accessToken": "mock-access-token",
6+
"refreshToken": "mock-refresh-token",
7+
"sessionExpiresAt": 5000000000000
8+
}
9+
]
File renamed without changes.

0 commit comments

Comments
 (0)