plugins/core/rest-api-plugin.js:18:import checkPermissionsMethod from './rest-api-plugin-methods/check-permissions.js'
plugins/core/rest-api-plugin.js:150:    addScopeMethod('checkPermissions', checkPermissionsMethod)
plugins/core/rest-api-multihome-plugin.js:2:  name: 'multihome',
plugins/core/rest-api-multihome-plugin.js:11:    const multihomeOptions = pluginOptions || {}
plugins/core/rest-api-multihome-plugin.js:14:    vars.multihome = {
plugins/core/rest-api-multihome-plugin.js:15:      field: multihomeOptions.field || 'multihome_id',
plugins/core/rest-api-multihome-plugin.js:16:      excludeResources: multihomeOptions.excludeResources || ['system_migrations', 'system_logs'],
plugins/core/rest-api-multihome-plugin.js:17:      requireAuth: multihomeOptions.requireAuth !== undefined ? multihomeOptions.requireAuth : true,
plugins/core/rest-api-multihome-plugin.js:18:      allowMissing: multihomeOptions.allowMissing || false
plugins/core/rest-api-multihome-plugin.js:52:      // Don't use 'www' or 'api' as tenant IDs
plugins/core/rest-api-multihome-plugin.js:58:      return request.headers?.['x-multihome-id'] || null
plugins/core/rest-api-multihome-plugin.js:62:    helpers.extractMultihomeId = multihomeOptions.extractor || defaultSubdomainExtractor
plugins/core/rest-api-multihome-plugin.js:64:    // Hook into transport layer to extract multihome_id
plugins/core/rest-api-multihome-plugin.js:65:    addHook('transport:request', 'extract-multihome-id', {}, async ({ context, request, helpers }) => {
plugins/core/rest-api-multihome-plugin.js:66:      // Extract multihome_id using configured extractor
plugins/core/rest-api-multihome-plugin.js:67:      const multihomeId = helpers.extractMultihomeId(request)
plugins/core/rest-api-multihome-plugin.js:69:      if (multihomeId) {
plugins/core/rest-api-multihome-plugin.js:72:        context.auth.multihome_id = multihomeId
plugins/core/rest-api-multihome-plugin.js:75:          multihome_id: multihomeId,
plugins/core/rest-api-multihome-plugin.js:78:      } else if (vars.multihome.requireAuth) {
plugins/core/rest-api-multihome-plugin.js:79:        log.warn('No multihome ID found in request', {
plugins/core/rest-api-multihome-plugin.js:86:    // Validate that resources have multihome field when added
plugins/core/rest-api-multihome-plugin.js:87:    addHook('scope:added', 'validate-multihome-field', {}, ({ context, vars }) => {
plugins/core/rest-api-multihome-plugin.js:91:      if (vars.multihome.excludeResources.includes(scopeName)) {
plugins/core/rest-api-multihome-plugin.js:92:        log.debug(`Resource ${scopeName} excluded from multihome validation`)
plugins/core/rest-api-multihome-plugin.js:96:      // Check if schema has multihome field
plugins/core/rest-api-multihome-plugin.js:98:      if (schema && !schema[vars.multihome.field]) {
plugins/core/rest-api-multihome-plugin.js:99:        if (vars.multihome.allowMissing) {
plugins/core/rest-api-multihome-plugin.js:100:          log.warn(`Resource ${scopeName} missing ${vars.multihome.field} field - multihome filtering disabled for this 
plugins/core/rest-api-multihome-plugin.js:104:              `Resource '${scopeName}' must have '${vars.multihome.field}' field in schema for multi-tenancy`
plugins/core/rest-api-multihome-plugin.js:111:    log.debug('Registering multihome filter hook')
plugins/core/rest-api-multihome-plugin.js:112:    addHook('knexQueryFiltering', 'multihome-filter', {}, async ({ context, vars }) => {
plugins/core/rest-api-multihome-plugin.js:117:      if (vars.multihome.excludeResources.includes(scopeName)) {
plugins/core/rest-api-multihome-plugin.js:118:        log.trace(`Skipping multihome filter for excluded resource: ${scopeName}`)
plugins/core/rest-api-multihome-plugin.js:122:      // Skip if no multihome context
plugins/core/rest-api-multihome-plugin.js:123:      if (!context.auth?.multihome_id) {
plugins/core/rest-api-multihome-plugin.js:124:        if (vars.multihome.requireAuth) {
plugins/core/rest-api-multihome-plugin.js:125:          throw new Error('No multihome context available - cannot execute query')
plugins/core/rest-api-multihome-plugin.js:130:      log.debug('Applying multihome tenant filter', {
plugins/core/rest-api-multihome-plugin.js:133:        tenant: context.auth.multihome_id,
plugins/core/rest-api-multihome-plugin.js:136:      // Check if this resource has multihome field
plugins/core/rest-api-multihome-plugin.js:138:      const hasMultihomeField = scope?.vars?.schemaInfo?.schemaStructure?.[vars.multihome.field]
plugins/core/rest-api-multihome-plugin.js:141:        if (vars.multihome.allowMissing) {
plugins/core/rest-api-multihome-plugin.js:142:          log.trace(`Resource ${scopeName} has no ${vars.multihome.field} field - skipping filter`)
plugins/core/rest-api-multihome-plugin.js:145:          throw new Error(`Resource ${scopeName} missing required ${vars.multihome.field} field`)
plugins/core/rest-api-multihome-plugin.js:155:        field: vars.multihome.field,
plugins/core/rest-api-multihome-plugin.js:161:      const tenantValue = translateFilterValue({
plugins/core/rest-api-multihome-plugin.js:162:        field: vars.multihome.field,
plugins/core/rest-api-multihome-plugin.js:163:        value: context.auth.multihome_id,
plugins/core/rest-api-multihome-plugin.js:168:      if (tenantValue === null) {
plugins/core/rest-api-multihome-plugin.js:171:        query.where(columnRef, tenantValue)
plugins/core/rest-api-multihome-plugin.js:174:      log.trace('Added multihome filter', {
plugins/core/rest-api-multihome-plugin.js:177:        multihome_id: context.auth.multihome_id
plugins/core/rest-api-multihome-plugin.js:181:    // Set multihome_id on new records
plugins/core/rest-api-multihome-plugin.js:182:    addHook('beforeSchemaValidate', 'set-multihome-id', {}, async ({ context, scopeName, vars }) => {
plugins/core/rest-api-multihome-plugin.js:184:      if (vars.multihome.excludeResources.includes(scopeName)) {
plugins/core/rest-api-multihome-plugin.js:188:      // Skip if no multihome context
plugins/core/rest-api-multihome-plugin.js:189:      if (!context.auth?.multihome_id) {
plugins/core/rest-api-multihome-plugin.js:190:        if (vars.multihome.requireAuth) {
plugins/core/rest-api-multihome-plugin.js:191:          throw new Error('Cannot create record without multihome context')
plugins/core/rest-api-multihome-plugin.js:196:      // Check if this resource has multihome field
plugins/core/rest-api-multihome-plugin.js:198:      const hasMultihomeField = scope?.vars?.schemaInfo?.schemaStructure?.[vars.multihome.field]
plugins/core/rest-api-multihome-plugin.js:201:        if (!vars.multihome.allowMissing) {
plugins/core/rest-api-multihome-plugin.js:202:          throw new Error(`Resource ${scopeName} missing required ${vars.multihome.field} field`)
plugins/core/rest-api-multihome-plugin.js:207:      // For POST, always set multihome_id
plugins/core/rest-api-multihome-plugin.js:210:        context.inputRecord.data.attributes[vars.multihome.field] = context.auth.multihome_id
plugins/core/rest-api-multihome-plugin.js:212:        log.debug('Set multihome_id on new record', {
plugins/core/rest-api-multihome-plugin.js:214:          multihome_id: context.auth.multihome_id
plugins/core/rest-api-multihome-plugin.js:218:      // For PUT/PATCH, validate multihome_id if provided
plugins/core/rest-api-multihome-plugin.js:220:            context.inputRecord.data.attributes?.[vars.multihome.field]) {
plugins/core/rest-api-multihome-plugin.js:221:        const providedId = context.inputRecord.data.attributes[vars.multihome.field]
plugins/core/rest-api-multihome-plugin.js:222:        if (providedId !== context.auth.multihome_id) {
plugins/core/rest-api-multihome-plugin.js:224:              `Cannot set ${vars.multihome.field} to '${providedId}' - must match current context '${context.auth.multihome_id}'`
plugins/core/rest-api-multihome-plugin.js:230:    // Add checkPermissions hook to enforce tenant isolation
plugins/core/rest-api-multihome-plugin.js:232:    addHook('checkPermissions', 'multihome-check-permissions', {}, async ({ context, scopeName }) => {
plugins/core/rest-api-multihome-plugin.js:239:      if (vars.multihome.excludeResources.includes(scopeName)) {
plugins/core/rest-api-multihome-plugin.js:243:      // Skip if no multihome context
plugins/core/rest-api-multihome-plugin.js:244:      if (!auth?.multihome_id) {
plugins/core/rest-api-multihome-plugin.js:245:        if (vars.multihome.requireAuth) {
plugins/core/rest-api-multihome-plugin.js:246:          throw new Error('No multihome context available')
plugins/core/rest-api-multihome-plugin.js:251:      // Get the scope to check if it has multihome field
plugins/core/rest-api-multihome-plugin.js:253:      const hasMultihomeField = scope?.vars?.schemaInfo?.schemaStructure?.[vars.multihome.field]
plugins/core/rest-api-multihome-plugin.js:256:        return // Resource doesn't support multihome
plugins/core/rest-api-multihome-plugin.js:259:      // For operations on existing records, verify tenant ownership
plugins/core/rest-api-multihome-plugin.js:261:        // minimalRecord is in JSON:API format, so tenant_id is in attributes
plugins/core/rest-api-multihome-plugin.js:262:        const recordTenant = minimalRecord.attributes?.[vars.multihome.field]
plugins/core/rest-api-multihome-plugin.js:263:        const userTenant = auth.multihome_id
plugins/core/rest-api-multihome-plugin.js:266:          log.error('Multihome permission violation', {
plugins/core/rest-api-multihome-plugin.js:281:            const error = new Error('Access denied - insufficient permissions')
plugins/core/rest-api-multihome-plugin.js:290:    // doesn't exist due to tenant filtering in the GET operation that precedes them
plugins/core/rest-api-multihome-plugin.js:292:    // Add API method to get current multihome context
plugins/core/rest-api-multihome-plugin.js:293:    api.multihome = {
plugins/core/rest-api-multihome-plugin.js:302:        ...vars.multihome,
plugins/core/rest-api-multihome-plugin.js:308:      field: vars.multihome.field,
plugins/core/rest-api-multihome-plugin.js:309:      excludedResources: vars.multihome.excludeResources,
plugins/core/rest-api-multihome-plugin.js:310:      requireAuth: vars.multihome.requireAuth,
plugins/core/rest-api-access.js:8:    const ownershipOptions = pluginOptions.ownership || pluginOptions.autoOwnership || {}
plugins/core/rest-api-access.js:11:      ownership: {
plugins/core/rest-api-access.js:12:        enabled: ownershipOptions.enabled !== false,
plugins/core/rest-api-access.js:13:        field: ownershipOptions.field || 'user_id',
plugins/core/rest-api-access.js:14:        userResource: ownershipOptions.userResource || 'users',
plugins/core/rest-api-access.js:15:        excludeResources: ownershipOptions.excludeResources || [],
plugins/core/rest-api-access.js:16:        filterByOwner: ownershipOptions.filterByOwner !== false,
plugins/core/rest-api-access.js:17:        requireOwnership: ownershipOptions.requireOwnership || false
plugins/core/rest-api-access.js:25:    const ownershipField = () => config.ownership.field
plugins/core/rest-api-access.js:27:    // Minimal helper: treat ownerField false/null as ownership disabled (alias)
plugins/core/rest-api-access.js:29:      scopeOptions?.ownership === false ||
plugins/core/rest-api-access.js:30:      scopeOptions?.ownerField === false ||
plugins/core/rest-api-access.js:31:      scopeOptions?.ownerField === null
plugins/core/rest-api-access.js:132:        const field = scopeVars?.ownershipField || ownershipField()
plugins/core/rest-api-access.js:135:        const ownershipStatus = evaluateOwnership({
plugins/core/rest-api-access.js:142:        return ownershipStatus === 'match'
plugins/core/rest-api-access.js:156:      scope.vars.ownershipField = context.scopeOptions?.ownershipField
plugins/core/rest-api-access.js:167:    addHook('schema:enrich', 'rest-auth-auto-ownership-field', {}, ({ context }) => {
plugins/core/rest-api-access.js:168:      if (!config.ownership.enabled) return
plugins/core/rest-api-access.js:170:      if (config.ownership.excludeResources.includes(scopeName)) return
plugins/core/rest-api-access.js:173:      const field = ownershipField()
plugins/core/rest-api-access.js:178:          fields[field].belongsTo = config.ownership.userResource
plugins/core/rest-api-access.js:188:        belongsTo: config.ownership.userResource,
plugins/core/rest-api-access.js:192:        description: 'Automatically managed ownership field'
plugins/core/rest-api-access.js:197:      if (!config.ownership.enabled) return
plugins/core/rest-api-access.js:198:      if (config.ownership.excludeResources.includes(scopeName)) return
plugins/core/rest-api-access.js:200:        if (config.ownership.requireOwnership) {
plugins/core/rest-api-access.js:208:      const field = ownershipField()
plugins/core/rest-api-access.js:213:      const shouldSet = scopeOptions?.ownership === true || (scopeOptions?.ownership === undefined && hasField)
plugins/core/rest-api-access.js:230:            type: fieldSchema.belongsTo || config.ownership.userResource || 'users',
plugins/core/rest-api-access.js:239:    addHook('beforeProcessingPost', 'rest-auth-auto-set-owner', {}, ({ context, scopeName, scopes, scopeOptions }) => {
plugins/core/rest-api-access.js:242:    addHook('beforeProcessingPatch', 'rest-auth-auto-set-owner', {}, ({ context, scopeName, scopes, scopeOptions }) => {
plugins/core/rest-api-access.js:245:    addHook('beforeProcessingPut', 'rest-auth-auto-set-owner', {}, ({ context, scopeName, scopes, scopeOptions }) => {
plugins/core/rest-api-access.js:249:    addHook('knexQueryFiltering', 'rest-auth-filter-by-owner', { sequence: -40 }, ({ context, scopes, scopeOptions }) => {
plugins/core/rest-api-access.js:250:      if (!config.ownership.enabled || !config.ownership.filterByOwner) return
plugins/core/rest-api-access.js:255:        throw new Error('AccessPlugin: knexQuery must provide query and tableName for ownership filtering')
plugins/core/rest-api-access.js:258:      if (config.ownership.excludeResources.includes(scopeName)) return
plugins/core/rest-api-access.js:260:        if (config.ownership.requireOwnership) {
plugins/core/rest-api-access.js:269:      const field = ownershipField()
plugins/core/rest-api-access.js:273:      const shouldFilter = scopeOptions?.ownership === true || (scopeOptions?.ownership === undefined && hasField)
plugins/core/rest-api-access.js:282:      const ownerValue = translateFilterValue({ field, value: context.auth.userId, scopeName, hookContext: context })
plugins/core/rest-api-access.js:284:      if (ownerValue === null) {
plugins/core/rest-api-access.js:287:        query.where(columnRef, ownerValue)
plugins/core/rest-api-access.js:291:    addHook('checkPermissions', 'rest-auth-enforce', { sequence: -100 }, async ({ context, scope, scopeName }) => {
plugins/core/rest-api-access.js:343:    addHook('checkPermissions', 'rest-auth-check-get-ownership', { sequence: -80 }, ({ context, scope, scopeName, scopeOptions }) => {
plugins/core/rest-api-access.js:344:      if (!config.ownership.enabled || !config.ownership.filterByOwner) return
plugins/core/rest-api-access.js:345:      if (config.ownership.excludeResources.includes(scopeName)) return
plugins/core/rest-api-access.js:354:      const field = ownershipField()
plugins/core/rest-api-access.js:357:      const shouldCheck = scopeOptions?.ownership === true || (scopeOptions?.ownership === undefined && hasField)
plugins/core/rest-api-access.js:374:      const ownershipStatus = evaluateOwnership({
plugins/core/rest-api-access.js:381:      if (ownershipStatus === 'mismatch') {
plugins/core/rest-api-access.js:401:      const field = ownershipField()
plugins/core/rest-api-access.js:403:      let ownerId
plugins/core/rest-api-access.js:406:        ownerId = resourceOrUserId[field]
plugins/core/rest-api-access.js:407:        if (!ownerId) {
plugins/core/rest-api-access.js:408:          throw new Error(`Resource does not have ownership field '${field}'`)
plugins/core/rest-api-access.js:411:        ownerId = resourceOrUserId
plugins/core/rest-api-access.js:413:        ownerId = context.existingRecord[field]
plugins/core/rest-api-access.js:414:        if (!ownerId) {
plugins/core/rest-api-access.js:415:          throw new Error(`Resource does not have ownership field '${field}'`)
plugins/core/rest-api-access.js:418:        throw new Error('No resource or user ID provided for ownership check')
plugins/core/rest-api-access.js:421:      if (String(auth.userId) !== String(ownerId)) {
plugins/core/rest-api-access.js:434:    helpers.auth.checkPermission = async function checkPermission (context, rules, options = {}) {
plugins/core/rest-api-plugin-methods/query.js:125:  // Centralised checkPermissions function
plugins/core/rest-api-plugin-methods/query.js:126:  await scope.checkPermissions({
plugins/core/rest-api-plugin-methods/get-relationship.js:30:  // Check permissions
plugins/core/rest-api-plugin-methods/get-relationship.js:31:  await runHooks('checkPermissions')
plugins/core/rest-api-plugin-methods/get-relationship.js:32:  await runHooks('checkPermissionsGetRelationship')
plugins/core/rest-api-plugin-methods/get-related.js:51:  // Check permissions
plugins/core/rest-api-plugin-methods/get-related.js:52:  await runHooks('checkPermissions')
plugins/core/rest-api-plugin-methods/get-related.js:53:  await runHooks('checkPermissionsGetRelated')
plugins/core/rest-api-plugin-methods/delete-relationship.js:47:    // Check permissions
plugins/core/rest-api-plugin-methods/delete-relationship.js:48:    await runHooks('checkPermissions')
plugins/core/rest-api-plugin-methods/delete-relationship.js:49:    await runHooks('checkPermissionsDeleteRelationship')
plugins/core/rest-api-plugin-methods/patch-relationship.js:23:    // Check permissions
plugins/core/rest-api-plugin-methods/patch-relationship.js:24:    await runHooks('checkPermissions')
plugins/core/rest-api-plugin-methods/patch-relationship.js:25:    await runHooks('checkPermissionsPatchRelationship')
plugins/core/rest-api-plugin-methods/common.js:445:        method: 'get', // We're checking read permission
plugins/core/rest-api-plugin-methods/common.js:460:      // Check permissions using the related scope's checkPermissions
plugins/core/rest-api-plugin-methods/common.js:461:      await relatedScope.checkPermissions({
plugins/core/rest-api-plugin-methods/patch.js:102:    // Centralised checkPermissions function
plugins/core/rest-api-plugin-methods/patch.js:103:    await scope.checkPermissions({
plugins/core/rest-api-plugin-methods/post-relationship.js:49:    // Check permissions
plugins/core/rest-api-plugin-methods/post-relationship.js:50:    await runHooks('checkPermissions')
plugins/core/rest-api-plugin-methods/post-relationship.js:51:    await runHooks('checkPermissionsPostRelationship')
plugins/core/rest-api-plugin-methods/get.js:88:  // Centralised checkPermissions function
plugins/core/rest-api-plugin-methods/get.js:89:  await scope.checkPermissions({
plugins/core/rest-api-plugin-methods/check-permissions.js:2: * checkPermissions
plugins/core/rest-api-plugin-methods/check-permissions.js:3: * Check if ther are permissions to access a resource.
plugins/core/rest-api-plugin-methods/check-permissions.js:6:export default async function checkPermissionsMethod ({ context, params, runHooks, scopeName, scopes, helpers }) {
plugins/core/rest-api-plugin-methods/check-permissions.js:12:  await runHooks('checkPermissions')
plugins/core/rest-api-plugin-methods/put.js:170:    // Centralised checkPermissions function
plugins/core/rest-api-plugin-methods/put.js:171:    await scope.checkPermissions({
plugins/core/rest-api-plugin-methods/delete.js:67:    // Centralised checkPermissions function
plugins/core/rest-api-plugin-methods/delete.js:68:    await scope.checkPermissions({
plugins/core/rest-api-plugin-methods/post.js:97:    // Centralised checkPermissions function
plugins/core/rest-api-plugin-methods/post.js:98:    await scope.checkPermissions({
