Skip to content

Commit cacbee6

Browse files
committed
fix: make test pass
1 parent 673ff91 commit cacbee6

File tree

15 files changed

+102
-56
lines changed

15 files changed

+102
-56
lines changed

api/src/core/adapters/dbApi/kysely/createPgSessionRepository.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ export function createPgSessionRepository(db: Kysely<Database>): SessionReposito
2121
email: null,
2222
accessToken: null,
2323
refreshToken: null,
24+
idToken: null,
2425
expiresAt: null,
2526
createdAt: new Date(),
2627
updatedAt: new Date()
@@ -34,7 +35,7 @@ export function createPgSessionRepository(db: Kysely<Database>): SessionReposito
3435
findById: async id => db.selectFrom("user_sessions").selectAll().where("id", "=", id).executeTakeFirst(),
3536

3637
update: async params => {
37-
const { id, userId, email, accessToken, refreshToken, expiresAt, loggedOutAt } = params;
38+
const { id, userId, email, accessToken, refreshToken, idToken, expiresAt, loggedOutAt } = params;
3839

3940
const result = await db
4041
.updateTable("user_sessions")
@@ -43,6 +44,7 @@ export function createPgSessionRepository(db: Kysely<Database>): SessionReposito
4344
email,
4445
accessToken,
4546
refreshToken,
47+
idToken,
4648
expiresAt,
4749
loggedOutAt,
4850
updatedAt: new Date()

api/src/core/adapters/dbApi/kysely/kysely.database.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@ type SessionsTable = {
164164
email: string | null;
165165
accessToken: string | null;
166166
refreshToken: string | null;
167+
idToken: string | null;
167168
expiresAt: Date | null;
168169
createdAt: Date;
169170
updatedAt: Date;

api/src/core/adapters/dbApi/kysely/migrations/1751616349982_create-sessions-table.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ export async function up(db: Kysely<any>): Promise<void> {
1414
.addColumn("email", "text")
1515
.addColumn("accessToken", "text")
1616
.addColumn("refreshToken", "text")
17+
.addColumn("idToken", "text")
1718
.addColumn("expiresAt", "timestamptz")
1819
.addColumn("createdAt", "timestamptz", col => col.notNull().defaultTo("now()"))
1920
.addColumn("updatedAt", "timestamptz", col => col.notNull().defaultTo("now()"))

api/src/core/adapters/fetchExternalData.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,7 @@ describe("fetches software extra data (from different providers)", () => {
325325
license: "Apache License v2.0",
326326
logoUrl:
327327
"//upload.wikimedia.org/wikipedia/commons/thumb/1/10/Apache_HTTP_server_logo_%282019-present%29.svg/250px-Apache_HTTP_server_logo_%282019-present%29.svg.png",
328-
sourceUrl: "https://github.com/apache/httpd",
328+
sourceUrl: "https://svn.apache.org/viewvc/httpd/httpd/",
329329
websiteUrl: "https://httpd.apache.org/",
330330
referencePublications: null,
331331
identifiers: [],

api/src/core/bootstrap.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ import { UiConfig, uiConfigSchema } from "./uiConfigSchema";
1919
import { UseCases } from "./usecases";
2020
import { makeHandleAuthCallback } from "./usecases/auth/handleAuthCallback";
2121
import { makeInitiateAuth } from "./usecases/auth/initiateAuth";
22-
import { makeLogout } from "./usecases/auth/logout";
23-
import { HttpOidcClient, type OidcParams } from "./usecases/auth/oidcClient";
22+
import { makeInitiateLogout } from "./usecases/auth/logout";
23+
import { HttpOidcClient, TestOidcClient, type OidcParams } from "./usecases/auth/oidcClient";
2424
import { makeGetUser } from "./usecases/getUser";
2525
import { makeGetSoftwareFormAutoFillDataFromExternalAndOtherSources } from "./usecases/getSoftwareFormAutoFillDataFromExternalAndOtherSources";
2626
import rawUiConfig from "../customization/ui-config.json";
@@ -32,6 +32,7 @@ type DbConfig = PgDbConfig;
3232
type ParamsOfBootstrapCore = {
3333
dbConfig: DbConfig;
3434
externalSoftwareDataOrigin: ExternalDataOrigin;
35+
oidcKind: "http" | "test";
3536
oidcParams: OidcParams;
3637
};
3738

@@ -75,7 +76,8 @@ export async function bootstrapCore(
7576

7677
const wikidataSource = await dbApi.source.getWikidataSource();
7778

78-
const oidcClient = await HttpOidcClient.create(oidcParams);
79+
const oidcClient =
80+
params.oidcKind === "http" ? await HttpOidcClient.create(oidcParams) : new TestOidcClient(oidcParams);
7981

8082
const useCases: UseCases = {
8183
getSoftwareFormAutoFillDataFromExternalAndOtherSources:
@@ -96,7 +98,7 @@ export async function bootstrapCore(
9698
userRepository: dbApi.user,
9799
oidcClient
98100
}),
99-
logout: makeLogout({ sessionRepository: dbApi.session, oidcClient })
101+
initiateLogout: makeInitiateLogout({ sessionRepository: dbApi.session, oidcClient })
100102
}
101103
};
102104

api/src/core/ports/DbApiV2.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ export type Session = {
140140
email: string | null;
141141
accessToken: string | null;
142142
refreshToken: string | null;
143+
idToken: string | null;
143144
expiresAt: Date | null;
144145
createdAt: Date;
145146
updatedAt: Date;

api/src/core/usecases/auth/auth.test.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,22 @@ import { Database } from "../../adapters/dbApi/kysely/kysely.database";
77
import { createPgDialect } from "../../adapters/dbApi/kysely/kysely.dialect";
88
import { expectToEqual, expectToMatchObject, testPgUrl } from "../../../tools/test.helpers";
99
import { HandleAuthCallback, makeHandleAuthCallback } from "./handleAuthCallback";
10-
import { makeLogout, Logout } from "./logout";
10+
import { makeInitiateLogout, InitiateLogout } from "./logout";
1111
import { createPgUserRepository } from "../../adapters/dbApi/kysely/createPgUserRepository";
1212

1313
describe("Authentication workflow", () => {
1414
let oidcClient: TestOidcClient;
1515
let initiateAuth: InitiateAuth;
1616
let handleAuthCallback: HandleAuthCallback;
17-
let logout: Logout;
17+
let initiateLogout: InitiateLogout;
1818
let db: Kysely<Database>;
1919

2020
beforeEach(async () => {
2121
oidcClient = new TestOidcClient({
2222
issuerUri: "https://auth.example.com",
2323
clientId: "test-client-id",
2424
clientSecret: "test-client-secret",
25-
redirectUri: "https://example.com/callback"
25+
appUrl: "https://example.com"
2626
});
2727

2828
db = new Kysely<Database>({ dialect: createPgDialect(testPgUrl) });
@@ -36,7 +36,7 @@ describe("Authentication workflow", () => {
3636
userRepository: createPgUserRepository(db),
3737
oidcClient
3838
});
39-
logout = makeLogout({
39+
initiateLogout = makeInitiateLogout({
4040
sessionRepository: createPgSessionRepository(db),
4141
oidcClient
4242
});
@@ -97,15 +97,18 @@ describe("Authentication workflow", () => {
9797
}
9898
]);
9999

100-
await logout({ sessionId });
100+
const { logoutUrl } = await initiateLogout({ sessionId });
101+
expectToEqual(typeof logoutUrl, "string");
102+
expectToEqual(logoutUrl.includes("logout"), true);
103+
101104
expectToEqual(oidcClient.calls, [
102105
{ method: "getAuthorizationEndpoint", args: [] },
103106
{ method: "exchangeCodeForTokens", args: [fakeCode] },
104107
{
105108
method: "getUserInfo",
106109
args: ["test-token-my-identity-provided-code"]
107110
},
108-
{ method: "logout", args: ["test-token-my-identity-provided-code"] }
111+
{ method: "logout", args: ["test-id-token-my-identity-provided-code"] }
109112
]);
110113

111114
const sessionAfterLogout = await db

api/src/core/usecases/auth/handleAuthCallback.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ export const makeHandleAuthCallback = ({
6969
email: userInfoFromProvider.email,
7070
accessToken: tokens.access_token,
7171
refreshToken: tokens.refresh_token ?? null,
72+
idToken: tokens.id_token ?? null,
7273
expiresAt: tokens.expires_in
7374
? new Date(Date.now() + tokens.expires_in * 1000)
7475
: new Date(Date.now() + twoDaysInMilliseconds)

api/src/core/usecases/auth/initiateAuth.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ export const makeInitiateAuth = ({ sessionRepository, oidcClient }: InitiateAuth
3333
client_id: oidcClient.clientId,
3434
redirect_uri: oidcClient.redirectUri,
3535
state,
36-
scope: "openid email profile given_name family_name usual_name name"
36+
scope: "openid email profile"
3737
}).toString();
3838

3939
return { sessionId, authUrl: authUrl.toString() };

api/src/core/usecases/auth/logout.ts

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,23 +5,30 @@
55
import { SessionRepository } from "../../ports/DbApiV2";
66
import { OidcClient } from "./oidcClient";
77

8-
type LogoutDependencies = {
8+
type InitiateLogoutDependencies = {
99
sessionRepository: SessionRepository;
1010
oidcClient: OidcClient;
1111
};
1212

13-
type LogoutParams = {
13+
type InitiateLogoutParams = {
1414
sessionId: string;
1515
};
1616

17-
export type Logout = ReturnType<typeof makeLogout>;
18-
export const makeLogout =
19-
({ sessionRepository, oidcClient }: LogoutDependencies) =>
20-
async ({ sessionId }: LogoutParams): Promise<void> => {
17+
export type InitiateLogout = ReturnType<typeof makeInitiateLogout>;
18+
export const makeInitiateLogout =
19+
({ sessionRepository, oidcClient }: InitiateLogoutDependencies) =>
20+
async ({ sessionId }: InitiateLogoutParams): Promise<{ logoutUrl: string }> => {
2121
const session = await sessionRepository.findById(sessionId);
2222

23-
if (!session) return;
23+
if (!session) {
24+
throw new Error(`Session not found: ${sessionId}`);
25+
}
2426

25-
await oidcClient.logout(session.accessToken);
27+
// Mark session as logged out immediately
2628
await sessionRepository.update({ ...session, loggedOutAt: new Date() });
29+
30+
// Get logout URL from OIDC client
31+
const logoutUrl = await oidcClient.logout(session.idToken);
32+
33+
return { logoutUrl };
2734
};

0 commit comments

Comments
 (0)