@@ -67,118 +67,3 @@ abstract class VerificationCodeStorageService {
6767 /// Disposes of any resources used by the service (e.g., timers for cleanup).
6868 void dispose ();
6969}
70-
71- /// {@template in_memory_verification_code_storage_service}
72- /// An in-memory implementation of [VerificationCodeStorageService] .
73- ///
74- /// Stores verification codes in memory. Not suitable for production if
75- /// persistence across server restarts is required.
76- /// {@endtemplate}
77- class InMemoryVerificationCodeStorageService
78- implements VerificationCodeStorageService {
79- /// {@macro in_memory_verification_code_storage_service}
80- InMemoryVerificationCodeStorageService ({
81- Duration cleanupInterval = _defaultCleanupInterval,
82- this .codeExpiryDuration = _defaultCodeExpiryDuration,
83- }) {
84- _cleanupTimer = Timer .periodic (cleanupInterval, (_) async {
85- try {
86- await cleanupExpiredCodes ();
87- } catch (e) {
88- print (
89- '[InMemoryVerificationCodeStorageService] Error during scheduled cleanup: $e ' ,
90- );
91- }
92- });
93- print (
94- '[InMemoryVerificationCodeStorageService] Initialized with cleanup interval: '
95- '$cleanupInterval and code expiry: $codeExpiryDuration ' ,
96- );
97- }
98-
99- /// Duration for which generated codes are considered valid.
100- final Duration codeExpiryDuration;
101-
102- /// Store for standard sign-in codes: Key is email.
103- @visibleForTesting
104- final Map <String , _SignInCodeEntry > signInCodesStore = {};
105-
106- Timer ? _cleanupTimer;
107- bool _isDisposed = false ;
108- final Random _random = Random ();
109-
110- String _generateNumericCode ({int length = 6 }) {
111- final buffer = StringBuffer ();
112- for (var i = 0 ; i < length; i++ ) {
113- buffer.write (_random.nextInt (10 ).toString ());
114- }
115- return buffer.toString ();
116- }
117-
118- @override
119- Future <String > generateAndStoreSignInCode (String email) async {
120- if (_isDisposed) {
121- throw const OperationFailedException ('Service is disposed.' );
122- }
123- await Future <void >.delayed (Duration .zero); // Simulate async
124- final code = _generateNumericCode ();
125- final expiresAt = DateTime .now ().add (codeExpiryDuration);
126- signInCodesStore[email] = _SignInCodeEntry (code, expiresAt);
127- print (
128- '[InMemoryVerificationCodeStorageService] Stored sign-in code: $code for $email (expires: $expiresAt )' ,
129- );
130- return code;
131- }
132-
133- @override
134- Future <bool > validateSignInCode (String email, String code) async {
135- if (_isDisposed) return false ;
136- await Future <void >.delayed (Duration .zero); // Simulate async
137- final entry = signInCodesStore[email];
138- if (entry == null || entry.isExpired || entry.code != code) {
139- return false ;
140- }
141- return true ;
142- }
143-
144- @override
145- Future <void > clearSignInCode (String email) async {
146- if (_isDisposed) return ;
147- await Future <void >.delayed (Duration .zero); // Simulate async
148- signInCodesStore.remove (email);
149- print (
150- '[InMemoryVerificationCodeStorageService] Cleared sign-in code for $email ' ,
151- );
152- }
153-
154- @override
155- Future <void > cleanupExpiredCodes () async {
156- if (_isDisposed) return ;
157- await Future <void >.delayed (Duration .zero); // Simulate async
158- var cleanedCount = 0 ;
159-
160- signInCodesStore.removeWhere ((key, entry) {
161- if (entry.isExpired) {
162- cleanedCount++ ;
163- return true ;
164- }
165- return false ;
166- });
167-
168- if (cleanedCount > 0 ) {
169- print (
170- '[InMemoryVerificationCodeStorageService] Cleaned up $cleanedCount expired codes.' ,
171- );
172- }
173- }
174-
175- @override
176- void dispose () {
177- if (! _isDisposed) {
178- _isDisposed = true ;
179- _cleanupTimer? .cancel ();
180- signInCodesStore.clear ();
181- print ('[InMemoryVerificationCodeStorageService] Disposed.' );
182- }
183- }
184- }
0 commit comments