
Research
Two Malicious Rust Crates Impersonate Popular Logger to Steal Wallet Keys
Socket uncovers malicious Rust crates impersonating fast_log to steal Solana and Ethereum wallet keys from source code.
@levante-framework/permissions-core
Advanced tools
A TypeScript package implementing a resource-based access control system for multi-site platforms. Designed for use in both frontend (Vue SPA) and backend (Firebase Cloud Functions) environments.
npm install permissions-service
import { PermissionService, CacheService } from 'permissions-service';
// Create cache instance (reuse across requests in Cloud Functions)
const cache = new CacheService();
// Create permission service
const permissions = new PermissionService(cache);
// Check if user can perform action
const canEdit = await permissions.hasPermission(
'user123',
'site456',
'groups',
'update'
);
if (canEdit) {
// User can edit groups
}
// functions/src/permissions.ts
import { PermissionService, CacheService } from 'permissions-service';
// Module-level cache for container persistence
const cache = new CacheService();
export const updateGroup = onCall(async (request) => {
const permissions = new PermissionService(cache);
const { userId, siteId } = request.auth;
// Check permission
const canUpdate = await permissions.hasPermission(
userId,
siteId,
'groups',
'update'
);
if (!canUpdate) {
throw new HttpsError('permission-denied', 'Insufficient permissions');
}
// Proceed with update
});
// composables/usePermissions.ts
import { PermissionService, CacheService } from 'permissions-service';
import { ref, computed } from 'vue';
// Session-level cache
const cache = new CacheService();
const permissions = new PermissionService(cache);
export function usePermissions() {
const currentUser = ref(null);
const currentSite = ref(null);
const canCreateGroups = computed(async () => {
if (!currentUser.value || !currentSite.value) return false;
return await permissions.hasPermission(
currentUser.value.id,
currentSite.value.id,
'groups',
'create'
);
});
return {
canCreateGroups,
hasPermission: permissions.hasPermission.bind(permissions)
};
}
The system implements a five-tier role hierarchy:
participant
- No admin dashboard accessresearch_assistant
- Read access + user creationadmin
- Subset of actions within their sitesite_admin
- Full control over their site's resourcessuper_admin
- Full system access across all sitesResource | Action | participant | research_assistant | admin | site_admin | super_admin |
---|---|---|---|---|---|---|
groups | create | ❌ | ❌ | ✅ | ✅ | ✅ |
groups | read | ❌ | ✅ | ✅ | ✅ | ✅ |
groups | update | ❌ | ❌ | ✅ | ✅ | ✅ |
groups | delete | ❌ | ❌ | ❌ | ✅ | ✅ |
users | create | ❌ | ✅ | ✅ | ✅ | ✅ |
users | read | ❌ | ✅ | ✅ | ✅ | ✅ |
admins | exclude | ❌ | ❌ | ❌ | ✅ | ✅ |
new PermissionService(cache?: CacheService)
hasPermission(userId, siteId, resource, action)
Check if a user has permission to perform an action on a resource.
const canEdit = await permissions.hasPermission(
'user123',
'site456',
'groups',
'update'
);
hasPermissions(userId, siteId, checks)
Bulk permission checking for multiple resource/action combinations.
const results = await permissions.hasPermissions('user123', 'site456', [
{ resource: 'groups', action: 'create' },
{ resource: 'users', action: 'read' }
]);
// Returns: [{ resource: 'groups', action: 'create', allowed: true }, ...]
getUserRole(userId, siteId)
Get the user's role for a specific site.
const role = await permissions.getUserRole('user123', 'site456');
// Returns: 'admin' | 'site_admin' | etc.
clearUserCache(userId)
Clear cached data for a specific user.
await permissions.clearUserCache('user123');
new CacheService(defaultTtl?: number) // Default: 5 minutes
get(key)
Retrieve cached value.
const value = cache.get('user:123:permissions');
set(key, value, ttl?)
Store value in cache with optional TTL.
cache.set('user:123:permissions', permissions, 300000); // 5 minutes
delete(key)
/ clear()
Remove specific key or clear entire cache.
cache.delete('user:123:permissions');
cache.clear();
Users must have the following structure in Firestore:
interface User {
id: string;
roles: Array<{
siteId: string;
role: 'participant' | 'research_assistant' | 'admin' | 'site_admin' | 'super_admin';
}>;
userType?: 'admin' | 'student' | 'teacher' | 'caregiver';
}
The system expects a permission matrix document at system/permissions
:
interface PermissionMatrix {
version: string;
permissions: {
[role: string]: {
[resource: string]: string[]; // Array of allowed actions
};
};
}
The service throws specific errors for different scenarios:
try {
const canEdit = await permissions.hasPermission(userId, siteId, 'groups', 'update');
} catch (error) {
if (error.message.includes('User not found')) {
// Handle missing user
} else if (error.message.includes('Permission matrix not found')) {
// Handle missing configuration
}
}
hasPermissions()
for multiple checkshasPermissions()
for multiple permission checksnpm run build # Compile TypeScript
npm run dev # Watch mode
npm run clean # Remove dist directory
npm test # Run tests in watch mode
npm run test:run # Run tests once
npm pack # Create tarball for local testing
This package replaces organization-based permissions with resource-based permissions. Key changes:
TBD
FAQs
Shared permissions service for front-end and back-end
We found that @levante-framework/permissions-core demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 4 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Socket uncovers malicious Rust crates impersonating fast_log to steal Solana and Ethereum wallet keys from source code.
Research
A malicious package uses a QR code as steganography in an innovative technique.
Research
/Security News
Socket identified 80 fake candidates targeting engineering roles, including suspected North Korean operators, exposing the new reality of hiring as a security function.