-
-
Notifications
You must be signed in to change notification settings - Fork 23
Refactor/leverage getdecorator api #102
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
jean-michelet
wants to merge
21
commits into
fastify:main
from
jean-michelet:refactor/leverage-getdecorator-api
Closed
Changes from all commits
Commits
Show all changes
21 commits
Select commit
Hold shift + click to select a range
5be081f
fix: remove console.log
jean-michelet 3460b55
Merge branch 'main' of github.com:jean-michelet/demo
jean-michelet 2876816
Merge branch 'main' of github.com:jean-michelet/demo
jean-michelet ff90149
Merge branch 'main' of github.com:jean-michelet/demo
jean-michelet 6420107
refactor: create and use tasks repository for tasks related db operat…
jean-michelet 386e2cc
refactor: put db/file operations into their own plugins
jean-michelet 8cc651e
refactor: encapsulate tasks file management
jean-michelet 9b3c67a
fix: conflicts
jean-michelet e686c40
refactor: extract reusable file logic into its own plugin
jean-michelet 154bcc1
docs: nit
jean-michelet 8ae575a
refactor: reorganize password management decorators into one decorato…
jean-michelet 9ada87e
refactor: encapsulate tasks stream into tasks repository
jean-michelet 01ab812
refactor: let errors propagate
jean-michelet 5f15dfe
fix: nit
jean-michelet 05576ba
docs: document rename strategy limitations
jean-michelet cdf058d
refactor: rename safeUnlink to unlink
jean-michelet 733ae12
feat: create safeJoin method for filename upload
jean-michelet 4739778
Merge branch 'main' of github.com:jean-michelet/demo into refactorisa…
jean-michelet cd86174
fix: conflicts
jean-michelet 2db56cd
refactor: leverage getdecorator api
jean-michelet b900627
fix: conflicts
jean-michelet File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import { FastifyRequest } from 'fastify' | ||
import fp from 'fastify-plugin' | ||
import { SessionData } from '../external/session.js' | ||
import { Auth } from '../../schemas/auth.js' | ||
|
||
export type Authenticate = OmitThisParameter<typeof authenticate> | ||
export const kAuth = Symbol('app.auth') | ||
export const kAuthenticate = Symbol('app.authenticate') | ||
|
||
function authenticate (this: FastifyRequest) { | ||
const { auth } = this.getDecorator<SessionData>('session') | ||
if (auth === undefined) { | ||
return false | ||
} | ||
|
||
// Instead of accessing the session directly in your application, | ||
// you should decorate the request. | ||
// This reduces coupling with the authentication strategy. | ||
// If you change or add new authentication strategies in the future, | ||
// `request.auth` remains the single source of truth. | ||
this.setDecorator<Auth>(kAuth, auth) | ||
|
||
return true | ||
} | ||
|
||
/** | ||
* The use of fastify-plugin is required to be able | ||
* to export the decorators to the outer scope | ||
* | ||
* @see {@link https://github.com/fastify/fastify-plugin} | ||
*/ | ||
export default fp( | ||
async function (fastify) { | ||
// Always decorate object instances before they are instantiated and used | ||
// @see https://fastify.dev/docs/latest/Reference/Decorators/#decorators | ||
fastify.decorateRequest(kAuth, null) | ||
fastify.decorateRequest(kAuthenticate, authenticate) | ||
}, | ||
// You should name your plugins if you want to avoid name collisions | ||
// and/or to perform dependency checks. | ||
{ name: 'authentication' } | ||
) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -1,26 +1,28 @@ | ||||||
import fp from 'fastify-plugin' | ||||||
import { FastifyReply, FastifyRequest } from 'fastify' | ||||||
import { Auth } from '../../schemas/auth.js' | ||||||
import { kAuth } from './authentication.js' | ||||||
|
||||||
declare module 'fastify' { | ||||||
export interface FastifyRequest { | ||||||
verifyAccess: typeof verifyAccess; | ||||||
isModerator: typeof isModerator; | ||||||
isAdmin: typeof isAdmin; | ||||||
} | ||||||
} | ||||||
export type AuthorizationManager = ReturnType<typeof createChecker> | ||||||
export const kAuthorizationManager = Symbol('app.authorizationManager') | ||||||
|
||||||
function verifyAccess (this: FastifyRequest, reply: FastifyReply, role: string) { | ||||||
if (!this.session.user.roles.includes(role)) { | ||||||
reply.status(403).send('You are not authorized to access this resource.') | ||||||
function createChecker () { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
function ensureHasRole (request: FastifyRequest, reply: FastifyReply, role: string) { | ||||||
const { roles } = request.getDecorator<Auth>(kAuth) | ||||||
if (!roles.includes(role)) { | ||||||
reply.status(403).send('You are not authorized to access this resource.') | ||||||
} | ||||||
} | ||||||
} | ||||||
|
||||||
async function isModerator (this: FastifyRequest, reply: FastifyReply) { | ||||||
this.verifyAccess(reply, 'moderator') | ||||||
} | ||||||
return { | ||||||
async ensureIsModerator (request: FastifyRequest, reply: FastifyReply) { | ||||||
return ensureHasRole(request, reply, 'moderator') | ||||||
}, | ||||||
|
||||||
async function isAdmin (this: FastifyRequest, reply: FastifyReply) { | ||||||
this.verifyAccess(reply, 'admin') | ||||||
async ensureIsAdmin (request: FastifyRequest, reply: FastifyReply) { | ||||||
return ensureHasRole(request, reply, 'admin') | ||||||
} | ||||||
} | ||||||
} | ||||||
|
||||||
/** | ||||||
|
@@ -31,9 +33,7 @@ async function isAdmin (this: FastifyRequest, reply: FastifyReply) { | |||||
*/ | ||||||
export default fp( | ||||||
async function (fastify) { | ||||||
fastify.decorateRequest('verifyAccess', verifyAccess) | ||||||
fastify.decorateRequest('isModerator', isModerator) | ||||||
fastify.decorateRequest('isAdmin', isAdmin) | ||||||
fastify.decorate(kAuthorizationManager, createChecker()) | ||||||
}, | ||||||
// You should name your plugins if you want to avoid name collisions | ||||||
// and/or to perform dependency checks. | ||||||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,15 @@ | ||
import { FastifyInstance } from 'fastify' | ||
import { Authenticate, kAuthenticate } from '../../plugins/app/authentication.js' | ||
|
||
export default async function (fastify: FastifyInstance) { | ||
fastify.addHook('onRequest', async (request, reply) => { | ||
if (request.url.startsWith('/api/auth/login')) { | ||
return | ||
} | ||
|
||
if (!request.session.user) { | ||
reply.unauthorized('You must be authenticated to access this route.') | ||
const success = request.getDecorator<Authenticate>(kAuthenticate)() | ||
if (!success) { | ||
return reply.unauthorized('You must be authenticated to access this route.') | ||
} | ||
}) | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,13 @@ | ||
import { FastifyInstance } from 'fastify' | ||
import { Auth } from '../../schemas/auth.js' | ||
import { kAuth } from '../../plugins/app/authentication.js' | ||
|
||
export default async function (fastify: FastifyInstance) { | ||
fastify.get('/', ({ session, protocol, hostname }) => { | ||
fastify.get('/', (request) => { | ||
const { username } = request.getDecorator<Auth>(kAuth) | ||
return { | ||
message: | ||
`Hello ${session.user.username}! See documentation at ${protocol}://${hostname}/documentation` | ||
`Hello ${username}! See documentation at ${request.protocol}://${request.hostname}/documentation` | ||
} | ||
}) | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.