Skip to content

feat(model): expose collections via read-only OAuth2Server getter #27#28

Open
alloalexandre wants to merge 1 commit into
leaonline:release/7.0.0from
alloalexandre:feature/expose-model-collections
Open

feat(model): expose collections via read-only OAuth2Server getter #27#28
alloalexandre wants to merge 1 commit into
leaonline:release/7.0.0from
alloalexandre:feature/expose-model-collections

Conversation

@alloalexandre

@alloalexandre alloalexandre commented Sep 16, 2025

Copy link
Copy Markdown

Summary

Exposes the MongoDB collections (AccessTokens, RefreshTokens, AuthCodes, Clients) via a read-only collections getter on OAuth2Server. The getter returns a frozen object to prevent mutations, ensuring OAuth2 compliance while allowing custom queries/indexing.

Changes

  • Exported collections from lib/model/meteor-model.js.
  • Assigned this.collections in OAuthMeteorModel constructor (lib/model/model.js).
  • Added get collections() getter to OAuth2Server (lib/oauth.js) using Object.freeze for read-only access.
  • Updated API.md via meteor npm run build:docs.
  • Added test in tests/model-tests.js to verify getter and read-only behavior.

Motivation

Users need direct access to collections for custom logic (e.g., querying expired tokens or creating indexes). This provides a safe, controlled way without exposing internal model details or requiring low-level MongoDB driver APIs.

Testing

  • All existing tests pass (meteor npm run test).
  • New test verifies collections getter returns Mongo.Collection instances and enforces read-only behavior.
  • Linter passes (meteor npm run lint).

Example Usage

import { OAuth2Server } from 'meteor/leaonline:oauth2-server';

const server = new OAuth2Server({ /* config */ });
const expiredTokens = server.collections.AccessTokens.find({
  accessTokenExpiresAt: { $lt: new Date() }
}).fetch();
console.log(expiredTokens); // Array of expired access tokens
// Mutation attempt fails:
server.collections.AccessTokens = {}; // TypeError: Cannot assign to read only property

Notes

  • No development Branch: The CONTRIBUTING.md mentioning development seems outdated.

@jankapunkt jankapunkt mentioned this pull request May 5, 2026
7 tasks
@jankapunkt
jankapunkt changed the base branch from master to release/7.0.0 May 5, 2026 06:00
@jankapunkt jankapunkt added this to the 7.0.0 milestone May 5, 2026
@jankapunkt
jankapunkt requested a review from Copilot July 6, 2026 08:24

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a public, read-only way to access the underlying Meteor/Mongo collections used by the default OAuth model via an OAuth2Server.collections getter, primarily to support custom queries and indexing.

Changes:

  • Added OAuth2Server.collections getter that returns a frozen collections object.
  • Exposed model collections on OAuthMeteorModel instances.
  • Added a test to verify the getter returns Mongo.Collection instances and prevents mutation.

Reviewed changes

Copilot reviewed 3 out of 4 changed files in this pull request and generated 2 comments.

File Description
tests/model-tests.js Adds a test covering the new OAuth2Server.collections getter and attempted mutation behavior.
lib/oauth.js Introduces the collections getter on OAuth2Server and freezes the returned object.
lib/model/model.js Assigns the model’s collections object onto OAuthMeteorModel instances for external access.
Comments suppressed due to low confidence (1)

lib/model/model.js:28

  • this.collections = collections makes it easy for consumers to treat model.collections as an instance-specific, mutable property, but it is actually a module-level singleton object (lib/model/meteor-model.js exports collections) and the property itself is reassignable. Consider defining the instance property as read-only after the collections are initialized to better match the PR’s “read-only exposure” intent and avoid accidental reassignment.
    this.debug = modelConfig.debug
    this.collections = collections
    collections.AccessTokens = createCollection(modelConfig.accessTokensCollection, modelConfig.accessTokensCollectionName)
    collections.RefreshTokens = createCollection(modelConfig.refreshTokensCollection, modelConfig.refreshTokensCollectionName)
    collections.AuthCodes = createCollection(modelConfig.authCodesCollection, modelConfig.authCodesCollectionName)
    collections.Clients = createCollection(modelConfig.clientsCollection, modelConfig.clientsCollectionName)

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread lib/oauth.js
Comment on lines +229 to +234
get collections () {
if (!this.model || !this.model.collections) {
throw new Error('Model collections not initialized. Ensure model is properly configured.')
}
return Object.freeze({ ...this.model.collections })
}
Comment thread tests/model-tests.js
Comment on lines +256 to +260
// Test read-only: attempting to mutate should throw
assert.throws(() => {
collections.AccessTokens = {}
}, /Cannot assign to read only property/, 'Should throw when attempting to mutate collections')
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants