To be honest, I am not sure what architecture has "domain" and "application" layers, but if you are interested in clean architecture, then I would suggest following the primary source, the book *Clean Architecture: A Craftsman’s Guide to Software Structure and Design* by Robert C. Martin.
To answer your question let's establish what layers the clean architecture consists of. Here is the quote from the book:
> The architect can employ the Single Responsibility Principle and the Common Closure Principle to separate those things that change for different reasons, and to collect those things that change for the same reasons—given the context of the intent of the system.
> What changes for different reasons?
>
> User interfaces change for reasons that have nothing to do with business rules. Business rules themselves may be closely tied to the application, or they may be more general. The database, the query language, and even the schema are technical details that have nothing to do with the business rules or the UI.
Thus we find the system divided into decoupled at least four horizontal layers — the **application-independent business rules**, **Application-specific business rules**, **UI**, and the **Database**.
Later in the book Robert Martin describes in detail how to build these 4 corresponding layers:
1. **Enterprise Business Rules (Entities)**
2. **Application Business Rules (Use Cases)**
3. **Interface Adapters**
4. **Frameworks & Drivers**.
[![enter image description here][1]][1]
[1]: https://i.stack.imgur.com/6MvWv.png
Now let's try to think, about what Robert Martin would answer to your question.
------------------------------------------------------------------------
> ... if I have a database instead of using the file system for the implementation, I will need a database login and therefore prompt a user. How does this fit in with Clean Architecture since the domain and
> application layers shouldn't know about implementation?
Inner layers should not know about the data source. Whether the data comes from a file system, a database, a web service, or any other source, it should not affect the business logic. The data access interfaces are defined in the gateways component from the interface adapters layer, but they are implemented in the frameworks and drivers layer. This way, the interface adapters layer can depend on abstractions, not concretions.
Now, let’s say you have a database as one of your data sources, and you need a database login to access it. How do you handle this requirement without violating the Clean Architecture concepts?
Here is a possible solution. You can use a user interface component to prompt the user for the database login information, and then using "gateways" interfaces pass this information outside to the outer layer (implementation). This way, you can let the user decide what login information to use, and you can also handle different scenarios such as invalid or expired credentials. The user interface component is part of the interface adapters layer, which communicates with the Application Business Rules through controllers or presenters and it communicates with frameworks & drivers using interfaces and their implementation. Additionally, you can use dependency injection to pass the database login information to the data access implementation at runtime. Or you can use environment variables or configuration files to store the database login information.
In summary, you can handle the database login requirement without breaking the Clean Architecture concepts by using techniques such as dependency injection, environment variables, configuration files, and interfaces.
Here is a typical scenario from the book for inspiration:
> If the application wants to display money on the screen, it might pass a Currency object to the Presenter. The Presenter will format that object with the appropriate decimal places and currency markers, creating a string that it can place in the View Model. If that currency value should be turned red if it is negative, then a simple boolean flag in the View model will be set appropriately.
Anything and everything that appears on the screen, and that the application has some kind of control over, is represented in the View Model as a string, a boolean, or an enum. Nothing is left for the View to do other than to load the data from the View Model into the screen.
If the application needs to know the last names of all the users who logged in yesterday, then the UserGateway interface will have a method named getLastNamesOfUsersWhoLoggedInAfter that takes a Date as its argument and returns a list of last names.
Let's refer to the primary source, the book "Clean Architecture: A Craftsman’s Guide to Software Structure and Design".
First of all, let's establish what layers the clean architecture consists of. Here is the quote from the book:
> The architect can employ the Single Responsibility Principle and the Common Closure Principle to separate those things that change for different reasons, and to collect those things that change for the same reasons—given the context of the intent of the system.
> What changes for different reasons?
>
> User interfaces change for reasons that have nothing to do with business rules. Business rules themselves may be closely tied to the application, or they may be more general. The database, the query language, and even the schema are technical details that have nothing to do with the business rules or the UI.
Thus we find the system divided into decoupled at least four horizontal layers — the **application-independent business rules**, **Application-specific business rules**, **UI**, and the **Database**.
Later in the book Robert Martin describes in detail how to build these 4 corresponding layers:
1. **Enterprise Business Rules (Entities)**
2. **Application Business Rules (Use Cases)**
3. **Interface Adapters**
4. **Frameworks & Drivers**.
[![enter image description here][1]][1]
Now let's establish what is "Use Case" is. Here is another quote:
> A use case is a description of the way an automated system is used. It specifies the input to be provided by the user, the output to be returned to the user, and the processing steps involved in producing that output.
>
> Those elements will be classes or functions or modules that have prominent positions within the architecture, and they will have names that clearly describe their function.
>
> From the use case, it is impossible to tell whether the application is delivered on the web, on a thick client, on a console or is a pure service.
>
> Between the ***use case** interactors* and the *database* are the database *gateways*. These *gateways* are polymorphic interfaces that contain methods for every create, read, update, or delete operation that can be performed by the application on the database.
>
> If the application needs to know the last names of all the users who logged in yesterday, then the *UserGateway* interface will have a method named *getLastNamesOfUsersWhoLoggedInAfter* that takes a Date as its argument and returns a list of last names.
*Now back to your question.*
Your description of the "SessionManager" sounds to me like an "AuthInterceptor". In my experience, I usually kept it as a part of the "data" component in the "Frameworks & Drivers" layer. Since it is in the "data" component, it is at the same level (circle) as database and web services. So theoretically there is no harm in accessing remote or local data sources directly (dao and rest client).
However, to be honest, when I did not have a decoupling layer, there were times when I used both and "gateway" and "use cases" in the "AuthInterceptor" (data component), which of probably a violation of the clean architecture, but I believe not as serious, because I still used these interfaces in outer circle, without braking the "boundaries" rule, that inner circle, should not know anything about outer circle.
Since Use Cases must have "*input to be provided by the user, the output to be returned to the user*", the "refreshToken" function will not be a part of this operation, because it does not involve the user at all, hence it will not be any of those two use cases that you mentioned, "LoginUseCase" and "LogoutUseCase".
Regarding your question on "LocalTokenSource", which you describe as a "repository", which by the Clean Architecture, would be correctly called "Gateway". Gateway interfaces are located in the "Interface Adapters" layer and their implementation is in the Frameworks & Drivers layer, so obviously, usage of the Gateway interface in two layers is not aligned with the clean architecture described in the book, but as I mentioned before, "Frameworks & Drivers" layer is an outermost circle, so it allowed to use anything that he knows about, which is the inner "Interface Adapters" layer.
If you understand the idea of the clean architecture described in the book and the references and experience that I provided, you will understand, that you do not need to violate anything, if you simply follow the basic structure and principles of Robert Martin's clean architecture.
[1]: https://i.stack.imgur.com/MzOSq.png