11// oxlint-disable class-methods-use-this
2- // oxlint-disable require-await
3-
4- import type {
5- AuthAdapter ,
6- AuthAdapterAuthorise ,
7- AuthAdapterOptions ,
8- StoryBookerUser ,
9- } from "@storybooker/core/adapter" ;
2+
3+ import {
4+ StoryBookerPermissionsList ,
5+ StoryBookerPermissionsAllEnabled ,
6+ type AuthAdapter ,
7+ type AuthAdapterOptions ,
8+ type StoryBookerPermissionAction ,
9+ type StoryBookerPermissionResource ,
10+ type StoryBookerPermissionWithKey ,
11+ type StoryBookerUser ,
12+ } from "@storybooker/core/adapter/auth" ;
1013import { Buffer } from "node:buffer" ;
1114
1215export type {
13- AuthAdapterAuthorise ,
1416 StoryBookerPermission ,
1517 StoryBookerPermissionAction ,
1618 StoryBookerPermissionKey ,
1719 StoryBookerPermissionResource ,
1820 StoryBookerPermissionWithKey ,
19- } from "@storybooker/core/adapter" ;
21+ } from "@storybooker/core/adapter/auth " ;
2022
2123export interface AzureEasyAuthClientPrincipal {
2224 claims : { typ : string ; val : string } [ ] ;
@@ -31,23 +33,24 @@ export interface AzureEasyAuthUser extends StoryBookerUser {
3133 clientPrincipal ?: AzureEasyAuthClientPrincipal ;
3234}
3335
36+ export type AuthAdapterAuthorise < AuthUser extends StoryBookerUser = StoryBookerUser > = (
37+ permission : StoryBookerPermissionWithKey ,
38+ user : Omit < AuthUser , "permissions" > ,
39+ ) => boolean ;
40+
3441/**
3542 * Modify the final user details object created from EasyAuth Client Principal.
3643 */
37- export type ModifyUserDetails = (
38- user : AzureEasyAuthUser ,
44+ export type ModifyUserDetails = < User extends Omit < AzureEasyAuthUser , "permissions" > > (
45+ user : User ,
3946 options : AuthAdapterOptions ,
40- ) => AzureEasyAuthUser | Promise < AzureEasyAuthUser > ;
47+ ) => User | Promise < User > ;
4148
42- const DEFAULT_AUTHORISE : AuthAdapterAuthorise < AzureEasyAuthUser > = ( { permission, user } ) => {
49+ const DEFAULT_AUTHORISE : AuthAdapterAuthorise < AzureEasyAuthUser > = ( permission , user ) => {
4350 if ( ! user ) {
4451 return false ;
4552 }
4653
47- if ( user . type === "application" ) {
48- return true ;
49- }
50-
5154 if ( permission . action === "read" ) {
5255 return true ;
5356 }
@@ -59,10 +62,15 @@ const DEFAULT_MODIFY_USER: ModifyUserDetails = (user) => user;
5962
6063/**
6164 * StoryBooker Auth adapter for Azure EasyAuth.
65+ *
66+ * @example
67+ * ```ts
68+ * const auth = new AzureEasyAuthService();
69+ * ```
6270 */
6371export class AzureEasyAuthService implements AuthAdapter < AzureEasyAuthUser > {
64- authorise : AuthAdapter < AzureEasyAuthUser > [ "authorise" ] ;
65- modifyUserDetails : ModifyUserDetails ;
72+ # authorise: AuthAdapterAuthorise < AzureEasyAuthUser > ;
73+ # modifyUserDetails: ModifyUserDetails ;
6674
6775 metadata : AuthAdapter [ "metadata" ] = { name : "Azure Easy Auth" } ;
6876
@@ -76,8 +84,8 @@ export class AzureEasyAuthService implements AuthAdapter<AzureEasyAuthUser> {
7684 */
7785 modifyUserDetails ?: ModifyUserDetails ;
7886 } ) {
79- this . authorise = options ?. authorise ?? DEFAULT_AUTHORISE ;
80- this . modifyUserDetails = options ?. modifyUserDetails ?? DEFAULT_MODIFY_USER ;
87+ this . # authorise = options ?. authorise ?? DEFAULT_AUTHORISE ;
88+ this . # modifyUserDetails = options ?. modifyUserDetails ?? DEFAULT_MODIFY_USER ;
8189 }
8290
8391 getUserDetails : AuthAdapter < AzureEasyAuthUser > [ "getUserDetails" ] = async ( options ) => {
@@ -100,10 +108,11 @@ export class AzureEasyAuthService implements AuthAdapter<AzureEasyAuthUser> {
100108 clientPrincipal,
101109 displayName : "App" ,
102110 id : azpToken ,
111+ permissions : StoryBookerPermissionsAllEnabled ,
103112 roles : null ,
104113 type : "application" ,
105114 } ;
106- return this . modifyUserDetails ( user , options ) ;
115+ return user ;
107116 }
108117
109118 const name = claims . find ( ( claim ) => claim . typ === "name" ) ?. val ;
@@ -112,18 +121,22 @@ export class AzureEasyAuthService implements AuthAdapter<AzureEasyAuthUser> {
112121 . filter ( ( claim ) => claim . typ === clientPrincipal . role_typ || claim . typ === "roles" )
113122 . map ( ( claim ) => claim . val ) ;
114123
115- const user : AzureEasyAuthUser = {
124+ const userWithoutPermissions : Omit < AzureEasyAuthUser , "permissions" > = {
116125 clientPrincipal,
117126 displayName : name ?? "" ,
118127 id : email ?? "" ,
119128 roles,
120129 title : roles . join ( ", " ) ,
121130 type : "user" ,
122131 } ;
123- return this . modifyUserDetails ( user , options ) ;
132+
133+ return {
134+ ...( await this . #modifyUserDetails( userWithoutPermissions , options ) ) ,
135+ permissions : authoriseUserPermissions ( this . #authorise, userWithoutPermissions ) ,
136+ } ;
124137 } ;
125138
126- login : AuthAdapter < AzureEasyAuthUser > [ "login" ] = async ( { request } ) => {
139+ login : AuthAdapter < AzureEasyAuthUser > [ "login" ] = ( { request } ) => {
127140 const url = new URL ( "/.auth/login" , request . url ) ;
128141
129142 return new Response ( null , {
@@ -132,7 +145,7 @@ export class AzureEasyAuthService implements AuthAdapter<AzureEasyAuthUser> {
132145 } ) ;
133146 } ;
134147
135- logout : AuthAdapter < AzureEasyAuthUser > [ "logout" ] = async ( _user , { request } ) => {
148+ logout : AuthAdapter < AzureEasyAuthUser > [ "logout" ] = ( _user , { request } ) => {
136149 const url = new URL ( "/.auth/logout" , request . url ) ;
137150
138151 return new Response ( null , {
@@ -141,3 +154,21 @@ export class AzureEasyAuthService implements AuthAdapter<AzureEasyAuthUser> {
141154 } ) ;
142155 } ;
143156}
157+
158+ function authoriseUserPermissions (
159+ authorise : AuthAdapterAuthorise < AzureEasyAuthUser > ,
160+ user : Omit < AzureEasyAuthUser , "permissions" > ,
161+ ) : AzureEasyAuthUser [ "permissions" ] {
162+ const permissions : AzureEasyAuthUser [ "permissions" ] = { } ;
163+
164+ for ( const key of StoryBookerPermissionsList ) {
165+ const [ resource , action ] = key . split ( ":" ) as [
166+ StoryBookerPermissionResource ,
167+ StoryBookerPermissionAction ,
168+ ] ;
169+ const permission : StoryBookerPermissionWithKey = { action, key, resource } ;
170+ permissions [ key ] = authorise ( permission , user ) ;
171+ }
172+
173+ return permissions ;
174+ }
0 commit comments