Skip to content

Adminforth user cleanup warning dialog #223

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: next
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions adminforth/modules/restApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,6 @@ export default class AdminForthRestAPI implements IAdminForthRestAPI {
const usernameColumn = userResource.columns.find((col) => col.name === usernameField);

const userPk = dbUser[userResource.columns.find((col) => col.primaryKey).name];

const userData = {
[this.adminforth.config.auth.usernameField]: username,
[this.adminforth.config.auth.userFullNameField]: userFullName,
Expand Down Expand Up @@ -291,7 +290,8 @@ export default class AdminForthRestAPI implements IAdminForthRestAPI {
}

const announcementBadge: AnnouncementBadgeResponse = this.adminforth.config.customization.announcementBadge?.(adminUser);

const adminforthUserCleanupWarning: AnnouncementBadgeResponse = this.adminforth.config.customization.adminforthUserCleanupWarning?.(adminUser);

const publicPart = {
brandName: this.adminforth.config.customization.brandName,
usernameFieldName: usernameColumn.label,
Expand All @@ -314,6 +314,7 @@ export default class AdminForthRestAPI implements IAdminForthRestAPI {
title: this.adminforth.config.customization.title,
emptyFieldPlaceholder: this.adminforth.config.customization.emptyFieldPlaceholder,
announcementBadge,
adminforthUserCleanupWarning,
globalInjections: this.adminforth.config.customization.globalInjections,
userFullnameField: this.adminforth.config.auth.userFullNameField,
}
Expand Down
24 changes: 22 additions & 2 deletions adminforth/spa/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,21 @@
</p>
<!-- <a class="text-sm text-lightPrimary underline font-medium hover:text-blue-900 dark:text-blue-400 dark:hover:text-blue-300" href="#">Turn new navigation off</a> -->
</div>

<div id="user-warning" class="p-4 mt-6 rounded-lg bg-red-900 dark:bg-red-900
fill-lightAnnouncementText dark:fill-darkAccent text-lightAnnouncementText dark:text-darkAccent text-sm" role="warning"
v-if="adminforthUserCleanupWarning">
<div class="flex items-center mb-3" :class="!adminforthUserCleanupWarning.title ? 'float-right' : ''">
<span>
<strong>
{{adminforthUserCleanupWarning.title}}
</strong>
</span>
</div>
<p class="mb-3 text-sm " v-if="adminforthUserCleanupWarning.html" v-html="adminforthUserCleanupWarning.html"></p>
<p class="mb-3 text-sm fill-lightNavbarText dark:fill-darkPrimary text-lightNavbarText dark:text-darkNavbarPrimary" v-else>
{{ adminforthUserCleanupWarning.text }}
</p>
</div>
<component
v-for="c in coreStore?.config?.globalInjections?.sidebar || []"
:is="getCustomComponent(c)"
Expand Down Expand Up @@ -434,8 +448,14 @@ function closeCTA() {
await coreStore.fetchMenuBadges();
adminforth.menu.refreshMenuBadges();
})

}

const adminforthUserCleanupWarning = computed(() => {
const badge = coreStore.config?.adminforthUserCleanupWarning;
if (!badge) return null;
if (process.env.NODE_ENV !== 'production' || coreStore.adminUser?.dbUser.email !== 'adminforth') return null;
return { ...badge };
});


</script>
8 changes: 7 additions & 1 deletion adminforth/types/Back.ts
Original file line number Diff line number Diff line change
Expand Up @@ -739,6 +739,13 @@ interface AdminForthInputConfigCustomization {
* Execution is done on admin app load.
*/
announcementBadge?: (user: AdminUser) => AnnouncementBadgeResponse,

/**
* Function to return custom badge in side bar for users. Can return text or html
* If function is not passed or returns null, badge will not be shown.
* Execution is done on admin app load.
*/
adminforthUserCleanupWarning?: (user: AdminUser) => AnnouncementBadgeResponse,

/**
* Custom panel components or array of components which will be displayed in the login form
Expand Down Expand Up @@ -964,7 +971,6 @@ export interface AdminForthInputConfig {
*/
rememberMeDays?: number,


/**
* Can be used to limit user access when subscribing from frontend to websocket topics.
* @param topic - topic where user is trying to subscribe
Expand Down
1 change: 1 addition & 0 deletions adminforth/types/Common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1058,6 +1058,7 @@ export interface AdminForthConfigForFrontend {
list?: string,
},
announcementBadge?: AnnouncementBadgeResponse | null,
adminforthUserCleanupWarning?: AnnouncementBadgeResponse | null,
globalInjections: {
userMenu: Array<AdminForthComponentDeclarationFull>,
header: Array<AdminForthComponentDeclarationFull>,
Expand Down
17 changes: 15 additions & 2 deletions dev-demo/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,19 @@ export const admin = new AdminForth({
}
},

adminforthUserCleanupWarning: (adminUser: AdminUser) => {
Copy link
Contributor

Choose a reason for hiding this comment

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

@NoOne7135 hm, small misunderstanding here. AF developer should not configure anything to see this error. This error is to protect AF users and AF developers from security breach, so once i will merge this PR I think it will change nothing..
How exactly AF developers will know that such feature exist at all? Do you think they will open common.ts and read for all possible options? I think this is not what you are generally doing when starting using some library of framework. If you will mention it somewhere in doc - also there is no guarantee user reads whole doc. And price for the fact he will not read whole doc should not be a security!
I see point why you make it configurable because string 'adminforth' comes from af developer code, but anyway I think message itself should be fully injected into adminforth code and should not be configurable. For now we can simply assume that user with name adminforth should not exist. Maybe as option we can pass option "auth.warnIfUserEmailIs: 'adminforth'" and make it in app created with cli...

return {
html: `
<p>The default admin user adminforth is still active in production.</p>
<p>For security reasons, it's strongly recommended to create your own account and delete this default user.</p>
<br>
<p><strong>This action is critical and cannot be undone.</strong></p>
`,
closable: false,
title: 'Critical Security Warning',
}
},

// loginPageInjections: {
// underInputs: '@@/login2.vue',
// }
Expand Down Expand Up @@ -506,8 +519,8 @@ admin.express.serve(app);
admin.discoverDatabases().then(async () => {
console.log('🅿️ Database discovered');

if (!await admin.resource('users').get([Filters.EQ('email', 'adminforth')])) {
await admin.resource('users').create({
if (await admin.resource('adminuser').count() === 0) {
await admin.resource('adminuser').create({
email: 'adminforth',
password_hash: await AdminForth.Utils.generatePasswordHash('adminforth'),
role: 'superadmin',
Expand Down