
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
@fire-shield/vue
Advanced tools
Vue adapter for RBAC with composables, directives, and navigation guards
Vue integration for Fire Shield RBAC authorization with composables, directives, and navigation guards.
useCan, useRole, useAuthorize, useAllPermissions, useAnyPermissionv-can, v-rolepnpm add @fire-shield/vue @fire-shield/core
# If using navigation guards, also install:
pnpm add vue-router
// main.ts
import { createApp } from 'vue';
import { createRouter } from 'vue-router';
import { RBAC } from '@fire-shield/core';
import { createFireShield } from '@fire-shield/vue';
const rbac = new RBAC();
rbac.createRole('admin', ['user:*', 'post:*']);
rbac.createRole('editor', ['post:read', 'post:write']);
const app = createApp(App);
const router = createRouter({ /* ... */ });
// Install Fire Shield plugin
app.use(createFireShield({
rbac,
router,
getUser: () => getCurrentUser() // Your user getter
}));
app.use(router);
app.mount('#app');
// router/index.ts
const routes = [
{
path: '/',
component: Home
},
{
path: '/admin',
component: AdminDashboard,
meta: {
permission: 'admin:access'
}
},
{
path: '/editor',
component: EditorPanel,
meta: {
role: 'editor'
}
},
{
path: '/users',
component: UserList,
meta: {
permission: 'user:read',
unauthorizedRedirect: '/forbidden'
}
}
];
<template>
<div>
<button v-if="$can('post:write')" @click="createPost">
Create Post
</button>
<button v-if="$hasRole('admin')" @click="openAdmin">
Admin Panel
</button>
<!-- Using directive -->
<div v-permission="'user:manage'">
<UserManagement />
</div>
<!-- Using component -->
<Can permission="post:delete">
<DeleteButton />
</Can>
</div>
</template>
<script setup>
import { useCan, useRole } from '@fire-shield/vue';
const canWrite = useCan('post:write');
const isEditor = useRole('editor');
function createPost() {
if (canWrite.value) {
// Create post
}
}
</script>
createFireShield({
rbac: RBAC,
router: Router,
getUser: () => RBACUser | Promise<RBACUser>,
unauthorizedRedirect?: string,
onUnauthorized?: (to, from, permission) => void
})
useRBAC()Returns RBAC instance.
const rbac = useRBAC();
const canDelete = rbac.hasPermission(user, 'post:delete');
useCan(permission)Reactive permission check.
const canWrite = useCan('post:write');
watchEffect(() => {
if (canWrite.value) {
// User has permission
}
});
useRole(role)Reactive role check.
const isAdmin = useRole('admin');
useAuthorize(permission)Reactive authorization result.
const result = useAuthorize('admin:delete');
watchEffect(() => {
if (!result.value.allowed) {
console.log('Denied:', result.value.reason);
}
});
useUser()Get current user.
const user = useUser();
console.log(user.value?.id, user.value?.roles);
$can(permission)Check permission in template.
<button v-if="$can('post:write')">Create</button>
$hasRole(role)Check role in template.
<div v-if="$hasRole('admin')">Admin Panel</div>
<Can>Conditionally render based on permission.
<Can permission="post:write">
<CreateButton />
</Can>
<Can role="admin">
<AdminPanel />
</Can>
<Can permission="post:write" v-slot="{ allowed }">
<button :disabled="!allowed">Create</button>
</Can>
<Cannot>Render when user lacks permission.
<Cannot permission="post:write">
<UpgradePrompt />
</Cannot>
v-permissionShow element only if user has permission.
<div v-permission="'admin:access'">
Admin content
</div>
<!-- With fallback -->
<div v-permission:user:manage="{ fallback: 'No access' }">
User management
</div>
v-roleShow element only if user has role.
<div v-role="'admin'">
Admin content
</div>
// router/index.ts
import { createRouter } from 'vue-router';
import { useRBAC } from '@fire-shield/vue';
const router = createRouter({ /* ... */ });
router.beforeEach((to, from, next) => {
const rbac = useRBAC();
const user = getCurrentUser();
// Check route permission
if (to.meta.permission) {
if (!rbac.hasPermission(user, to.meta.permission as string)) {
return next('/unauthorized');
}
}
// Check route role
if (to.meta.role) {
if (!user.roles.includes(to.meta.role as string)) {
return next('/unauthorized');
}
}
next();
});
<template>
<nav>
<router-link to="/">Home</router-link>
<router-link v-if="$can('post:manage')" to="/posts">
Posts
</router-link>
<router-link v-if="$can('user:manage')" to="/users">
Users
</router-link>
<router-link v-if="$hasRole('admin')" to="/admin">
Admin
</router-link>
</nav>
</template>
<template>
<div class="actions">
<button
v-for="action in availableActions"
:key="action.permission"
@click="action.handler"
>
{{ action.label }}
</button>
</div>
</template>
<script setup>
import { computed } from 'vue';
import { useCan } from '@fire-shield/vue';
const actions = [
{ label: 'Edit', permission: 'post:edit', handler: editPost },
{ label: 'Delete', permission: 'post:delete', handler: deletePost },
{ label: 'Publish', permission: 'post:publish', handler: publishPost },
];
const availableActions = computed(() => {
return actions.filter(action => useCan(action.permission).value);
});
</script>
<template>
<form>
<input v-model="form.name" />
<input
v-if="canEditEmail"
v-model="form.email"
type="email"
/>
<select
v-if="canEditRole"
v-model="form.role"
>
<option value="user">User</option>
<option value="editor">Editor</option>
<option v-if="isAdmin" value="admin">Admin</option>
</select>
</form>
</template>
<script setup>
import { useCan, useRole } from '@fire-shield/vue';
const canEditEmail = useCan('user:edit:email');
const canEditRole = useCan('user:edit:role');
const isAdmin = useRole('admin');
const form = reactive({
name: '',
email: '',
role: 'user'
});
</script>
<template>
<Can permission="admin:access">
<div class="admin-panel">
<h1>Admin Panel</h1>
<section v-permission="'user:manage'">
<h2>User Management</h2>
<UserList />
</section>
<section v-permission="'post:manage'">
<h2>Post Management</h2>
<PostList />
</section>
</div>
</Can>
</template>
// main.ts
import { BufferedAuditLogger } from '@fire-shield/core';
const auditLogger = new BufferedAuditLogger(
async (events) => {
await fetch('/api/audit-logs', {
method: 'POST',
body: JSON.stringify({ events })
});
},
{ maxBufferSize: 50, flushIntervalMs: 3000 }
);
const rbac = new RBAC({ auditLogger });
import type { RBACUser } from '@fire-shield/core';
interface User extends RBACUser {
email: string;
name: string;
}
// Typed composables
const user = useUser<User>();
const canWrite = useCan('post:write');
DIB © Fire Shield Team
FAQs
Vue adapter for RBAC with composables, directives, and navigation guards
We found that @fire-shield/vue demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer 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.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.