SharePointAccessValidator¶
SharePointAccessValidator is a customer-owned access validation hook that the framework calls before minting or using SharePoint tokens. Implement this interface to enforce your application's authorization rules, such as audit firm membership, assignment checks, SharePoint enablement, and folder scope restrictions.
Import¶
Interface¶
interface SharePointAccessValidator {
validateAccess(userId: number, auditingId: number): Promise<AccessValidationResult>;
}
AccessValidationResult¶
| Field | Type | Description |
|---|---|---|
valid | boolean | true if the user is authorized to access SharePoint for the given auditing context. |
reason | string | Human-readable reason when valid is false. Included in the error thrown by SharePointAuth. |
How It Is Used¶
SharePointAuth.getAccessToken() calls validateAccess() before every token request (including cached token returns). If validation fails, getAccessToken() throws an error with the provided reason.
sequenceDiagram
participant Auth as SharePointAuth
participant AV as AccessValidator
participant Caller
Caller->>Auth: getAccessToken(userId, auditingId)
Auth->>AV: validateAccess(userId, auditingId)
alt Access granted
AV-->>Auth: { valid: true }
Auth-->>Caller: access token
else Access denied
AV-->>Auth: { valid: false, reason: "..." }
Auth-->>Caller: throws Error(reason)
end Implementation Example¶
import { SharePointAccessValidator, AccessValidationResult } from "@modernpath/agent-framework";
class MyAccessValidator implements SharePointAccessValidator {
constructor(
private readonly userService: UserService,
private readonly auditingService: AuditingService,
) {}
async validateAccess(userId: number, auditingId: number): Promise<AccessValidationResult> {
// 1. Check user exists and is active
const user = await this.userService.findById(userId);
if (!user || !user.isActive) {
return { valid: false, reason: "User not found or inactive" };
}
// 2. Check user has SharePoint enabled
if (!user.sharePointEnabled) {
return { valid: false, reason: "SharePoint access not enabled for this user" };
}
// 3. Check user is assigned to the auditing
const assignment = await this.auditingService.getAssignment(userId, auditingId);
if (!assignment) {
return { valid: false, reason: "User is not assigned to this auditing" };
}
// 4. Check auditing has SharePoint configured
const auditing = await this.auditingService.findById(auditingId);
if (!auditing?.sharePointSiteId) {
return { valid: false, reason: "Auditing does not have SharePoint configured" };
}
return { valid: true };
}
}
Simple Allow-All Validator (Development)¶
const devValidator: SharePointAccessValidator = {
async validateAccess(_userId, _auditingId) {
return { valid: true };
},
};
Wiring with SharePointAuth¶
import { SharePointAuth } from "@modernpath/agent-framework";
const validator = new MyAccessValidator(userService, auditingService);
const auth = new SharePointAuth(
{
tenantId: process.env.AZURE_TENANT_ID!,
clientId: process.env.AZURE_CLIENT_ID!,
clientSecret: process.env.AZURE_CLIENT_SECRET!,
useOnBehalfOfExchange: true,
},
tokenProvider,
validator,
);
// This will call validator.validateAccess() before returning a token
try {
const token = await auth.getAccessToken(userId, auditingId);
} catch (err) {
// err.message contains the validation reason
console.error("Access denied:", err.message);
}
Related Pages¶
- SharePointAuth -- the auth provider that calls this validator
- SharePointGraphClient -- using validated tokens with Graph API