Skip to content

Commit 77d331c

Browse files
committed
fix(internal): Restructure auth and guard middlewares
Mostly naming tweaks for clarity
1 parent 586e77d commit 77d331c

8 files changed

Lines changed: 31 additions & 28 deletions

File tree

apps/miiverse-api/src/services/internal/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@ import { postsRouter } from '@/services/internal/routes/posts';
44

55
export const internalApiRouter = express.Router();
66
internalApiRouter.use('/api/v1', testRouter);
7-
internalApiRouter.use('/api/v1/posts', postsRouter);
7+
internalApiRouter.use('/api/v1', postsRouter);

apps/miiverse-api/src/services/internal/middleware/check-user-account.ts renamed to apps/miiverse-api/src/services/internal/middleware/auth-accesscheck.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import type express from 'express';
44
/**
55
* Checks the user account is valid for this request (not banned, setup complete, etc.)
66
*/
7-
async function checkUserAccount(request: express.Request, response: express.Response, next: express.NextFunction): Promise<void> {
7+
export async function authAccessCheck(request: express.Request, response: express.Response, next: express.NextFunction): Promise<void> {
88
const account = response.locals.account;
99
if (account === null) {
1010
// Guest access
@@ -19,5 +19,3 @@ async function checkUserAccount(request: express.Request, response: express.Resp
1919

2020
return next();
2121
}
22-
23-
export default checkUserAccount;

apps/miiverse-api/src/services/internal/middleware/authentication.ts renamed to apps/miiverse-api/src/services/internal/middleware/auth-populate.ts

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import type { AccountData } from '@/types/common/account-data';
88
* Handles authentication for service (NNAS/console) and OAuth (web) tokens. Sets locals.account to AccountData.
99
* Will error if tokens bad or account nonexistent, but otherwise does not check bans or setup status.
1010
*/
11-
async function auth(request: express.Request, response: express.Response, next: express.NextFunction): Promise<void> {
11+
export async function authPopulate(request: express.Request, response: express.Response, next: express.NextFunction): Promise<void> {
1212
// Used by console applets
1313
const serviceToken = getValueFromHeaders(request.headers, 'x-service-token');
1414
// Used by web frontend
@@ -19,9 +19,9 @@ async function auth(request: express.Request, response: express.Response, next:
1919
}
2020

2121
if (serviceToken) {
22-
response.locals.account = await consoleAuth(serviceToken);
22+
response.locals.account = await consoleAuth(request, serviceToken);
2323
} else if (oAuthToken) {
24-
response.locals.account = await webAuth(oAuthToken);
24+
response.locals.account = await webAuth(request, oAuthToken);
2525
} else {
2626
// Guest access
2727
response.locals.account = null;
@@ -30,34 +30,33 @@ async function auth(request: express.Request, response: express.Response, next:
3030
return next();
3131
}
3232

33-
async function consoleAuth(serviceToken: string): Promise<AccountData> {
33+
async function consoleAuth(_request: express.Request, serviceToken: string): Promise<AccountData> {
3434
const pid = getPIDFromServiceToken(serviceToken);
3535
if (pid === 0) {
3636
throw new errors.unauthorized('Invalid service token');
3737
}
3838

39-
const pnid = await getUserAccountData(pid);
4039
// If the user has a valid token for an unknown PID, just let the exception bubble
40+
const pnid = await getUserAccountData(pid);
4141

42-
const settings = await getUserSettings(pid) ?? undefined; // Null doesn't play nice with TS ?
43-
// Undef here just means the initial setup isn't done
42+
// Null here just means the initial setup isn't done
43+
const settings = await getUserSettings(pid);
4444

4545
return { pnid, settings };
4646
}
4747

48-
async function webAuth(oAuthToken: string): Promise<AccountData> {
48+
async function webAuth(request: express.Request, oAuthToken: string): Promise<AccountData> {
4949
// The "normal" getUserData API (used here) is mutually incompatible with the "backdoor" one.
5050
// Since we can only use the backdoor one for consoles right now...
51-
const pid = (await getUserDataFromToken(oAuthToken).catch(() => {
51+
const pid = (await getUserDataFromToken(oAuthToken).catch((e) => {
5252
// TODO should probably check the error type here in case of e.g. connection refused
53+
request.log.error(e, 'Failed to get user data from OAuth token');
5354
throw new errors.unauthorized('Invalid OAuth token!');
5455
})).pid;
5556
// Ask the "backdoor" API, just use the above as a glorified token decryption.
5657
const pnid = await getUserAccountData(pid);
5758

58-
const settings = await getUserSettings(pid) ?? undefined;
59+
const settings = await getUserSettings(pid);
5960

6061
return { pnid, settings };
6162
}
62-
63-
export default auth;

apps/miiverse-api/src/services/internal/middleware/authenticated-endpoints.ts renamed to apps/miiverse-api/src/services/internal/middleware/guards.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@ import type express from 'express';
44
/**
55
* Guest access is fine
66
*/
7-
export async function authGuest(request: express.Request, response: express.Response, next: express.NextFunction): Promise<void> {
7+
export async function guest(request: express.Request, response: express.Response, next: express.NextFunction): Promise<void> {
88
return next();
99
}
1010

1111
/**
1212
* Fail on guest access
1313
*/
14-
export async function authUsers(request: express.Request, response: express.Response, next: express.NextFunction): Promise<void> {
14+
export async function user(request: express.Request, response: express.Response, next: express.NextFunction): Promise<void> {
1515
const account = response.locals.account;
1616
if (account === null) {
1717
// Guest access
@@ -24,7 +24,7 @@ export async function authUsers(request: express.Request, response: express.Resp
2424
/**
2525
* Moderators only
2626
*/
27-
export async function authModerators(request: express.Request, response: express.Response, next: express.NextFunction): Promise<void> {
27+
export async function moderator(request: express.Request, response: express.Response, next: express.NextFunction): Promise<void> {
2828
const account = response.locals.account;
2929
if (account === null) {
3030
// Guest access
@@ -37,3 +37,9 @@ export async function authModerators(request: express.Request, response: express
3737

3838
return next();
3939
}
40+
41+
export const guards = {
42+
guest,
43+
user,
44+
moderator
45+
};

apps/miiverse-api/src/services/internal/routes/posts.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@ import express from 'express';
22
import { getPostByID } from '@/database';
33
import { errors } from '@/services/internal/errors';
44
import { handle } from '@/services/internal/utils';
5-
import { authGuest } from '@/services/internal/middleware/authenticated-endpoints';
5+
import { guards } from '@/services/internal/middleware/guards';
66
import { mapPost } from '@/services/internal/contract/post';
77

88
export const postsRouter = express.Router();
99

10-
postsRouter.get('/:post_id', authGuest, handle(async ({ req }) => {
10+
postsRouter.get('/posts/:post_id', guards.guest, handle(async ({ req }) => {
1111
const post = await getPostByID(req.params.post_id);
1212
if (!post || post.removed) {
1313
throw new errors.notFound('Post not found');

apps/miiverse-api/src/services/internal/routes/test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import express from 'express';
22
import { handle } from '@/services/internal/utils';
3-
import { authUsers } from '@/services/internal/middleware/authenticated-endpoints';
3+
import { guards } from '@/services/internal/middleware/guards';
44

55
export const testRouter = express.Router();
66

7-
testRouter.get('/test', authUsers, handle(async () => {
7+
testRouter.get('/test', guards.user, handle(async () => {
88
return {
99
message: 'Hello from the test route!'
1010
};

apps/miiverse-api/src/services/internal/server.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,20 @@ import express from 'express';
44
import { MiiverseServiceDefinition } from '@repo/grpc-client/out/miiverse_service';
55
import { config } from '@/config';
66
import { internalApiRouter } from '@/services/internal';
7-
import authentication from '@/services/internal/middleware/authentication';
8-
import checkUserAccount from '@/services/internal/middleware/check-user-account';
97
import { logger } from '@/logger';
108
import { InternalAPIError } from '@/services/internal/errors';
119
import { loggerHttp } from '@/loggerHttp';
10+
import { authPopulate } from '@/services/internal/middleware/auth-populate';
11+
import { authAccessCheck } from '@/services/internal/middleware/auth-accesscheck';
1212
import type { CallContext, ServerMiddlewareCall } from 'nice-grpc';
1313

1414
// API server
1515

1616
const app = express();
1717
app.use(express.json());
1818
app.use(loggerHttp);
19-
app.use(authentication);
20-
app.use(checkUserAccount);
19+
app.use(authPopulate);
20+
app.use(authAccessCheck);
2121
app.use(internalApiRouter);
2222

2323
// API error handler

apps/miiverse-api/src/types/common/account-data.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@ import type { GetUserDataResponse } from '@pretendonetwork/grpc/account/get_user
33

44
export interface AccountData {
55
pnid: GetUserDataResponse;
6-
settings?: HydratedSettingsDocument;
6+
settings: HydratedSettingsDocument | null;
77
}

0 commit comments

Comments
 (0)