Skip to content

Commit 48067fd

Browse files
committed
feat: rename 'rememberMeDays' to 'rememberMeDuration' across the codebase and update related logic for session duration handling
1 parent 1531685 commit 48067fd

File tree

8 files changed

+59
-35
lines changed

8 files changed

+59
-35
lines changed

adminforth/auth.ts

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -76,27 +76,19 @@ class AdminForthAuth implements IAdminForthAuth {
7676
response.setHeader('Set-Cookie', `adminforth_${brandSlug}_jwt=; Path=${this.adminforth.config.baseUrl || '/'}; HttpOnly; SameSite=Strict; Expires=Thu, 01 Jan 1970 00:00:00 GMT`);
7777
}
7878

79-
setAuthCookie({ expireInDays, response, username, pk}: {
80-
expireInDays?: number,
79+
setAuthCookie({ expireInDuration, response, username, pk}: {
80+
expireInDuration?: string,
8181
response: any,
8282
username: string,
8383
pk: string | null
8484
}) {
85-
console.log("in days", expireInDays);
86-
const expiresIn: string = expireInDays ? `${expireInDays}d` : (process.env.ADMINFORTH_AUTH_EXPIRESIN || '24h');
87-
console.log("in string", expiresIn);
85+
const expiresIn: string = expireInDuration || (process.env.ADMINFORTH_AUTH_EXPIRESIN || '24h');
8886
// might be h,m,d in string
89-
9087
const expiresInSec = parseTimeToSeconds(expiresIn);
9188

92-
console.log("expiresInSec", expiresInSec);
93-
94-
const token = this.issueJWT({ username, pk}, 'auth', expiresIn);
95-
console.log("token", token);
89+
const token = this.issueJWT({ username, pk}, 'auth', expiresInSec);
9690
const expiresCookieFormat = new Date(Date.now() + expiresInSec * 1000).toUTCString();
97-
console.log("expiresCookieFormat", expiresCookieFormat);
9891
const brandSlug = this.adminforth.config.customization.brandNameSlug;
99-
console.log("brandSlug", brandSlug);
10092
response.setHeader('Set-Cookie', `adminforth_${brandSlug}_jwt=${token}; Path=${this.adminforth.config.baseUrl || '/'}; HttpOnly; SameSite=Strict; Expires=${expiresCookieFormat}`);
10193
}
10294

@@ -131,7 +123,7 @@ class AdminForthAuth implements IAdminForthAuth {
131123
return cookies.find((cookie) => cookie.key === `adminforth_${brandSlug}_${name}`)?.value || null;
132124
}
133125

134-
issueJWT(payload: Object, type: string, expiresIn: string = '24h'): string {
126+
issueJWT(payload: Object, type: string, expiresIn: string | number = '24h'): string {
135127
// read ADMINFORH_SECRET from environment if not drop error
136128
const secret = process.env.ADMINFORTH_SECRET;
137129
if (!secret) {

adminforth/commands/createApp/templates/index.ts.hbs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ export const admin = new AdminForth({
1414
usersResourceId: 'adminuser',
1515
usernameField: 'email',
1616
passwordHashField: 'password_hash',
17-
rememberMeDays: 30,
17+
rememberMeDuration: '30d',
1818
loginBackgroundImage: 'https://images.unsplash.com/photo-1534239697798-120952b76f2b?q=80&w=3389&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
1919
loginBackgroundPosition: '1/2',
2020
loginPromptHTML: async () => {

adminforth/documentation/docs/tutorial/03-Customization/12-security.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,14 @@ You can tweak login cookie expiration time by setting environment `ADMINFORTH_AU
1111
ADMINFORTH_AUTH_EXPIRESIN=1h
1212
```
1313

14-
Also you can set `auth.rememberMeDays` in the config to set how long "remember me" logins will last.
14+
Also you can set `auth.rememberMeDuration` in the config to set how long "remember me" logins will last.
1515
For example to set it to 7 days:
1616

1717
```ts ./index.ts
1818
new AdminForth({
1919
...
2020
auth: {
21-
rememberMeDays: 7
21+
rememberMeDuration: '7d' // '7d' for 7 days, '24h' for 24 hours, '30m' for 30 minutes, etc.
2222
}
2323
}
2424
```

adminforth/modules/configValidator.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1141,6 +1141,33 @@ export default class ConfigValidator implements IConfigValidator {
11411141
}
11421142
}
11431143

1144+
if (newConfig.auth.rememberMeDays !== undefined) {
1145+
const rememberMeDays = newConfig.auth.rememberMeDays;
1146+
if (typeof rememberMeDays !== 'number' || rememberMeDays <= 0) {
1147+
errors.push(`auth.rememberMeDays must be a positive number`);
1148+
} else {
1149+
if (!newConfig.auth.rememberMeDuration) {
1150+
newConfig.auth.rememberMeDuration = `${rememberMeDays}d`;
1151+
warnings.push(`⚠️ auth.rememberMeDays is deprecated. Please use auth.rememberMeDuration: "${rememberMeDays}d" instead. Auto-converted for now.`);
1152+
} else {
1153+
warnings.push(`⚠️ Both auth.rememberMeDays and auth.rememberMeDuration are set. Using rememberMeDuration. Please remove rememberMeDays.`);
1154+
}
1155+
}
1156+
delete newConfig.auth.rememberMeDays;
1157+
}
1158+
1159+
if (newConfig.auth.rememberMeDuration !== undefined) {
1160+
const duration = newConfig.auth.rememberMeDuration;
1161+
if (typeof duration !== 'string') {
1162+
errors.push(`auth.rememberMeDuration must be a string in format "1s", "1m", "1h", or "1d"`);
1163+
} else {
1164+
const match = duration.match(/^(\d+)([smhd])$/);
1165+
if (!match) {
1166+
errors.push(`auth.rememberMeDuration must be in format "1s", "1m", "1h", or "1d" (e.g., "30d" for 30 days), got: "${duration}"`);
1167+
}
1168+
}
1169+
}
1170+
11441171
// normalize beforeLoginConfirmation hooks
11451172
const blc = this.inputConfig.auth.beforeLoginConfirmation;
11461173
if (!Array.isArray(blc)) {

adminforth/modules/restApi.ts

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ export default class AdminForthRestAPI implements IAdminForthRestAPI {
129129
this.adminforth = adminforth;
130130
}
131131

132-
async processLoginCallbacks(adminUser: AdminUser, toReturn: { redirectTo?: string, allowedLogin:boolean, error?: string }, response: any, extra: HttpExtra, rememberMeDays?: number) {
132+
async processLoginCallbacks(adminUser: AdminUser, toReturn: { redirectTo?: string, allowedLogin:boolean, error?: string }, response: any, extra: HttpExtra, sessionDuration?: string) {
133133
const beforeLoginConfirmation = this.adminforth.config.auth.beforeLoginConfirmation as (BeforeLoginConfirmationFunction[] | undefined);
134134

135135
for (const hook of listify(beforeLoginConfirmation)) {
@@ -138,7 +138,7 @@ export default class AdminForthRestAPI implements IAdminForthRestAPI {
138138
response,
139139
adminforth: this.adminforth,
140140
extra,
141-
rememberMeDays
141+
sessionDuration,
142142
});
143143

144144
if (resp?.body?.redirectTo || resp?.error) {
@@ -205,17 +205,19 @@ export default class AdminForthRestAPI implements IAdminForthRestAPI {
205205
username,
206206
};
207207

208-
const expireInDays = rememberMe ? this.adminforth.config.auth.rememberMeDays || 30 : 1;
209-
208+
const expireInDuration = rememberMe
209+
? (this.adminforth.config.auth.rememberMeDuration || '30d')
210+
: '1d';
211+
console.log('expireInDuration', expireInDuration);
210212

211213
await this.processLoginCallbacks(adminUser, toReturn, response, {
212214
body, headers, query, cookies, requestUrl,
213-
}, expireInDays);
215+
}, expireInDuration);
214216

215217
if (toReturn.allowedLogin) {
216218

217219
this.adminforth.auth.setAuthCookie({
218-
expireInDays,
220+
expireInDuration,
219221
response,
220222
username,
221223
pk: userRecord[userResource.columns.find((col) => col.primaryKey).name]
@@ -289,7 +291,7 @@ export default class AdminForthRestAPI implements IAdminForthRestAPI {
289291
everyPageBottom: this.adminforth.config.customization.globalInjections.everyPageBottom,
290292
sidebarTop: this.adminforth.config.customization.globalInjections.sidebarTop,
291293
},
292-
rememberMeDays: this.adminforth.config.auth.rememberMeDays,
294+
rememberMeDuration: this.adminforth.config.auth.rememberMeDuration,
293295
singleTheme: this.adminforth.config.customization.singleTheme,
294296
customHeadItems: this.adminforth.config.customization.customHeadItems,
295297
};
@@ -381,7 +383,7 @@ export default class AdminForthRestAPI implements IAdminForthRestAPI {
381383
title: this.adminforth.config.customization?.title,
382384
demoCredentials: this.adminforth.config.auth.demoCredentials,
383385
loginPageInjections: this.adminforth.config.customization.loginPageInjections,
384-
rememberMeDays: this.adminforth.config.auth.rememberMeDays,
386+
rememberMeDuration: this.adminforth.config.auth.rememberMeDuration,
385387
singleTheme: this.adminforth.config.customization.singleTheme,
386388
customHeadItems: this.adminforth.config.customization.customHeadItems,
387389
}

adminforth/spa/src/views/LoginView.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,9 @@
7676
</Input>
7777
</div>
7878

79-
<div v-if="coreStore.config.rememberMeDays"
79+
<div v-if="coreStore.config.rememberMeDuration"
8080
class="flex items-start mb-5"
81-
:title="$t(`Stay logged in for {days} days`, {days: coreStore.config.rememberMeDays})"
81+
:title="$t(`Stay logged in for {days}`, {days: coreStore.config.rememberMeDuration})"
8282
>
8383
<Checkbox v-model="rememberMeValue" class="mr-2">
8484
{{ $t('Remember me') }}

adminforth/types/Back.ts

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -303,15 +303,15 @@ export interface IAdminForthDataSourceConnectorConstructor {
303303
export interface IAdminForthAuth {
304304
verify(jwt : string, mustHaveType: string, decodeUser?: boolean): Promise<any>;
305305

306-
issueJWT(payload: Object, type: string, expiresIn?: string): string;
306+
issueJWT(payload: Object, type: string, expiresIn?: string | number): string;
307307

308308
removeCustomCookie({response, name}: {response: any, name: string}): void;
309309

310310
setCustomCookie({response, payload}: {response: any, payload: {name: string, value: string, expiry: number, expirySeconds: number, httpOnly: boolean}}): void;
311311

312312
getCustomCookie({cookies, name}: {cookies: {key: string, value: string}[], name: string}): string | null;
313313

314-
setAuthCookie({expireInDays, response, username, pk,}: {expireInDays?: number, response: any, username: string, pk: string}): void;
314+
setAuthCookie({expireInDuration, response, username, pk,}: {expireInDuration?: string, response: any, username: string, pk: string}): void;
315315

316316
removeAuthCookie(response: any): void;
317317

@@ -331,8 +331,9 @@ export interface IAdminForthRestAPI {
331331
* @param adminUser - plugin/af pases current adminUser
332332
* @param toReturn - this is an object which will get status of login process. If at least one callback returns error or redirectTo, login process will be stopped (future callbacks will not be called).
333333
* @param response - http response object
334+
* @param sessionDuration - duration of session in format "1s", "1m", "1h", or "1d" (e.g., "30d" for 30 days)
334335
*/
335-
processLoginCallbacks(adminUser: AdminUser, toReturn: { redirectTo?: string, allowedLogin: boolean, error?: string }, response: any, extra: HttpExtra): Promise<void>;
336+
processLoginCallbacks(adminUser: AdminUser, toReturn: { redirectTo?: string, allowedLogin: boolean, error?: string }, response: any, extra: HttpExtra, sessionDuration?: string): Promise<void>;
336337
}
337338

338339
export interface IAdminForth {
@@ -605,7 +606,7 @@ export type BeforeLoginConfirmationFunction = (params?: {
605606
response: IAdminForthHttpResponse,
606607
adminforth: IAdminForth,
607608
extra?: HttpExtra,
608-
rememberMeDays?: number,
609+
sessionDuration?: string,
609610
}) => Promise<{
610611
error?: string,
611612
body: {
@@ -1053,11 +1054,13 @@ export interface AdminForthInputConfig {
10531054
loginPromptHTML?: string | (() => string | void | undefined | Promise<string | void | undefined>) | undefined
10541055

10551056
/**
1056-
* Remember me days for "Remember Me" checkbox on login page.
1057-
* If not set or set to null/0/undefined, "Remember Me" checkbox will not be displayed.
1058-
* If rememberMeDays is set, then users who check "Remember Me" will be staying logged in for this amount of days.
1057+
* Remember me duration for "Remember Me" checkbox on login page.
1058+
* If not set or set to null/undefined, "Remember Me" checkbox will not be displayed.
1059+
* If rememberMeDuration is set, then users who check "Remember Me" will be staying logged in for this amount of time.
1060+
* Format: "1s" (seconds), "1m" (minutes), "1h" (hours), or "1d" (days).
1061+
* Example: "30d" for 30 days, "7d" for 7 days, "24h" for 24 hours.
10591062
*/
1060-
rememberMeDays?: number,
1063+
rememberMeDuration?: string,
10611064

10621065

10631066
/**

adminforth/types/Common.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1119,7 +1119,7 @@ export interface AdminForthConfigForFrontend {
11191119
underInputs: Array<AdminForthComponentDeclaration>,
11201120
panelHeader: Array<AdminForthComponentDeclaration>,
11211121
},
1122-
rememberMeDays: number,
1122+
rememberMeDuration: string,
11231123
showBrandNameInSidebar: boolean,
11241124
showBrandLogoInSidebar: boolean,
11251125
brandLogo?: string,

0 commit comments

Comments
 (0)