1
+ /**
2
+ * EN: Real World Example for the Chain of Responsibility Design Pattern
3
+ *
4
+ * Need: Handle different types of authentication in an HTTP request
5
+ *
6
+ * Solution: Create a chain of authentication handlers, where each handler
7
+ * checks a specific authentication type. If a handler can't authenticate the
8
+ * request, it passes the request to the next handler in the chain.
9
+ */
10
+
11
+ /**
12
+ * EN: The Handler interface declares a method for building the chain of
13
+ * handlers. It also declares a method for executing a request.
14
+ *
15
+ * RU: Интерфейс Обработчика объявляет метод построения цепочки обработчиков. Он
16
+ * также объявляет метод для выполнения запроса.
17
+ */
18
+ interface Handler < Request = string , Result = string > {
19
+ setNext ( handler : Handler < Request , Result > ) : Handler < Request , Result > ;
20
+
21
+ handle ( request : Request ) : Result ;
22
+ }
23
+ /**
24
+ * EN: The AuthenticationHandler interface declares a method for authenticating
25
+ * an HTTP request.
26
+ */
27
+ interface AuthenticationHandler
28
+ extends Handler < AuthenticationRequest , AuthenticationResult > { }
29
+
30
+ /**
31
+ * EN: The AuthenticationRequest represents an HTTP request that needs to be
32
+ * authenticated
33
+ */
34
+ type AuthenticationRequest = {
35
+ user ?: {
36
+ name : string ;
37
+ password : string ;
38
+ } ;
39
+ apiKey ?: string ;
40
+ jwtToken ?: string ;
41
+ } ;
42
+
43
+ /**
44
+ * EN: The AuthenticationResult represents the result of an authentication
45
+ * attempt
46
+ */
47
+ type AuthenticationResult = {
48
+ success : boolean ,
49
+ message : string
50
+ }
51
+
52
+ /**
53
+ * EN: The base AbstractAuthenticationHandler implements the default chaining
54
+ * behavior
55
+ */
56
+ abstract class AbstractAuthenticationHandler implements AuthenticationHandler {
57
+ private nextHandler : AuthenticationHandler ;
58
+
59
+ public setNext ( handler : AuthenticationHandler ) : AuthenticationHandler {
60
+ this . nextHandler = handler ;
61
+ return handler ;
62
+ }
63
+
64
+ public handle ( request : AuthenticationRequest ) : AuthenticationResult {
65
+ if ( this . nextHandler ) {
66
+ return this . nextHandler . handle ( request ) ;
67
+ }
68
+
69
+ return { success : false , message : 'Unable to authenticate user.' } ;
70
+ }
71
+ }
72
+
73
+ /**
74
+ * EN: All Concrete Handlers either handle a request or pass it to the next
75
+ * handler in the chain.
76
+ *
77
+ * RU: Все Конкретные Обработчики либо обрабатывают запрос, либо передают его
78
+ * следующему обработчику в цепочке.
79
+ */
80
+ class BasicAuthenticationHandler extends AbstractAuthenticationHandler {
81
+ public handle ( request : AuthenticationRequest ) : AuthenticationResult {
82
+ const user = request . user ;
83
+ if ( user . name === 'admin' && user . password === 'password' ) {
84
+ return {
85
+ success : true ,
86
+ message : 'User authenticated with basic authentication.'
87
+ } ;
88
+ }
89
+ return super . handle ( request ) ;
90
+ }
91
+ }
92
+
93
+ class ApiKeyAuthenticationHandler extends AbstractAuthenticationHandler {
94
+ public handle ( request : AuthenticationRequest ) : AuthenticationResult {
95
+ if ( request . apiKey === 'my-api-key' ) {
96
+ return {
97
+ success : true , message : 'User authenticated with API key.'
98
+ } ;
99
+ }
100
+ return super . handle ( request ) ;
101
+ }
102
+ }
103
+
104
+ class JwtAuthenticationHandler extends AbstractAuthenticationHandler {
105
+ public handle ( request : AuthenticationRequest ) : AuthenticationResult {
106
+ if ( request . jwtToken === 'my-jwt-token' ) {
107
+ return {
108
+ success : true , message : 'User authenticated with JWT token.'
109
+ } ;
110
+ }
111
+ return super . handle ( request ) ;
112
+ }
113
+ }
0 commit comments