diff --git a/src/sbbs3/js_msg_area.c b/src/sbbs3/js_msg_area.c
index 1c21e1c78814a7dec71fd9309ec5a6ab5979e100..13a31ee2eca42245c0facde0ba1e15995b793e0a 100644
--- a/src/sbbs3/js_msg_area.c
+++ b/src/sbbs3/js_msg_area.c
@@ -57,6 +57,7 @@ static char* msg_area_prop_desc[] = {
 
 	 "sub-board number"
 	,"group number"
+	,"group name"
 	,"sub-board internal code"
 	,"sub-board name"
 	,"sub-board description"
@@ -109,6 +110,12 @@ BOOL DLLCALL js_CreateMsgAreaProperties(JSContext* cx, scfg_t* cfg, JSObject* su
 		,NULL,NULL,JSPROP_ENUMERATE|JSPROP_READONLY))
 		return(FALSE);
 
+	if((js_str=JS_NewStringCopyZ(cx, cfg->grp[sub->grp]->sname))==NULL)
+		return(FALSE);
+	if(!JS_DefineProperty(cx, subobj, "grp_name", STRING_TO_JSVAL(js_str)
+		,NULL,NULL,JSPROP_ENUMERATE|JSPROP_READONLY))
+		return(FALSE);
+
 	if((js_str=JS_NewStringCopyZ(cx, sub->code))==NULL)
 		return(FALSE);
 	if(!JS_DefineProperty(cx, subobj, "code", STRING_TO_JSVAL(js_str)
@@ -318,6 +325,7 @@ JSObject* DLLCALL js_CreateMsgAreaObject(JSContext* cx, JSObject* parent, scfg_t
 {
 	JSObject*	areaobj;
 	JSObject*	allsubs;
+	JSObject*	allgrps;
 	JSObject*	grpobj;
 	JSObject*	subobj;
 	JSObject*	grp_list;
@@ -325,7 +333,7 @@ JSObject* DLLCALL js_CreateMsgAreaObject(JSContext* cx, JSObject* parent, scfg_t
 	JSString*	js_str;
 	jsval		val;
 	jsuint		index;
-	uint		l,d;
+	uint		l,d,gn;
 
 	/* Return existing object if it's already been created */
 	if(JS_GetProperty(cx,parent,"msg_area",&val) && val!=JSVAL_VOID)
@@ -348,6 +356,13 @@ JSObject* DLLCALL js_CreateMsgAreaObject(JSContext* cx, JSObject* parent, scfg_t
 	if(!JS_SetProperty(cx, areaobj, "sub", &val))
 		return(NULL);
 
+	if((allgrps=JS_NewObject(cx, NULL, NULL, areaobj))==NULL)
+		return(NULL);
+
+	val=OBJECT_TO_JSVAL(allgrps);
+	if(!JS_SetProperty(cx, areaobj, "grp", &val))
+		return(NULL);
+
 	/* grp_list[] */
 	if((grp_list=JS_NewArrayObject(cx, 0, NULL))==NULL) 
 		return(NULL);
@@ -356,7 +371,7 @@ JSObject* DLLCALL js_CreateMsgAreaObject(JSContext* cx, JSObject* parent, scfg_t
 	if(!JS_SetProperty(cx, areaobj, "grp_list", &val)) 
 		return(NULL);
 
-	for(l=0;l<cfg->total_grps;l++) {
+	for(l=gn=0;l<cfg->total_grps;l++) {
 
 #if 0
 		if(user==NULL && (*cfg->grp[l]->ar)!=AR_NULL)
@@ -375,9 +390,15 @@ JSObject* DLLCALL js_CreateMsgAreaObject(JSContext* cx, JSObject* parent, scfg_t
 		if(!JS_SetElement(cx, grp_list, index, &val))
 			return(NULL);
 
-		val=INT_TO_JSVAL(l);
+		/* Add as property (associative array element) */
+		if(!JS_DefineProperty(cx, allgrps, cfg->grp[l]->sname, val
+			,NULL,NULL,JSPROP_READONLY|JSPROP_ENUMERATE))
+			return(NULL);
+
+		val=INT_TO_JSVAL(gn);
 		if(!JS_SetProperty(cx, grpobj, "number", &val))
 			return(NULL);
+		gn++;
 
 		if((js_str=JS_NewStringCopyZ(cx, cfg->grp[l]->sname))==NULL)
 			return(NULL);
@@ -500,6 +521,11 @@ JSObject* DLLCALL js_CreateMsgAreaObject(JSContext* cx, JSObject* parent, scfg_t
 	JS_DefineProperty(cx,allsubs,"_dont_document",JSVAL_TRUE,NULL,NULL,JSPROP_READONLY);
 #endif
 
+#ifdef _DEBUG
+	js_DescribeSyncObject(cx,allsubs,"Associative array of all groups (use name as index)",312);
+	JS_DefineProperty(cx,allgrps,"_dont_document",JSVAL_TRUE,NULL,NULL,JSPROP_READONLY);
+#endif
+
 	return(areaobj);
 }