Documentation
¶
Index ¶
- type AdminService
- type AuthService
- type BuddyListRegistry
- type BuddyService
- type ChatNavService
- type ChatRegistry
- func (c *ChatRegistry) Add(room wire.ICBMRoomInfo) int
- func (c *ChatRegistry) LookupRoom(chatID int) (wire.ICBMRoomInfo, bool)
- func (c *ChatRegistry) RegisterSess(chatID int, sess *state.Session)
- func (c *ChatRegistry) RemoveSess(chatID int)
- func (c *ChatRegistry) RetrieveSess(chatID int) *state.Session
- func (c *ChatRegistry) Sessions() []*state.Session
- type ChatService
- type CookieBaker
- type DirSearchService
- type ICBMService
- type IPRateLimiter
- type LocateService
- type OSCARProxy
- func (s OSCARProxy) AddBuddy(ctx context.Context, me *state.Session, args []byte) string
- func (s OSCARProxy) AddDeny(ctx context.Context, me *state.Session, args []byte) string
- func (s OSCARProxy) AddPermit(ctx context.Context, me *state.Session, args []byte) string
- func (s OSCARProxy) AuthMiddleware(next http.Handler) http.Handler
- func (s OSCARProxy) ChangePassword(ctx context.Context, me *state.Session, args []byte) string
- func (s OSCARProxy) ChatAccept(ctx context.Context, me *state.Session, chatRegistry *ChatRegistry, ...) (int, string)
- func (s OSCARProxy) ChatIn(ctx context.Context, snac wire.SNAC_0x0E_0x06_ChatChannelMsgToClient, ...) string
- func (s OSCARProxy) ChatInvite(ctx context.Context, me *state.Session, chatRegistry *ChatRegistry, ...) string
- func (s OSCARProxy) ChatJoin(ctx context.Context, me *state.Session, chatRegistry *ChatRegistry, ...) (int, string)
- func (s OSCARProxy) ChatLeave(ctx context.Context, chatRegistry *ChatRegistry, args []byte) string
- func (s OSCARProxy) ChatSend(ctx context.Context, chatRegistry *ChatRegistry, args []byte) string
- func (s OSCARProxy) ChatUpdateBuddyArrived(snac wire.SNAC_0x0E_0x03_ChatUsersJoined, chatID int) string
- func (s OSCARProxy) ChatUpdateBuddyLeft(snac wire.SNAC_0x0E_0x04_ChatUsersLeft, chatID int) string
- func (s OSCARProxy) ChatWhisper(ctx context.Context, chatRegistry *ChatRegistry, args []byte) string
- func (s OSCARProxy) DirInfoHandler(w http.ResponseWriter, request *http.Request)
- func (s OSCARProxy) DirSearchHandler(w http.ResponseWriter, r *http.Request)
- func (s OSCARProxy) Evil(ctx context.Context, me *state.Session, args []byte) string
- func (s OSCARProxy) Eviled(snac wire.SNAC_0x01_0x10_OServiceEvilNotification) string
- func (s OSCARProxy) FormatNickname(ctx context.Context, me *state.Session, args []byte) string
- func (s OSCARProxy) GetDirSearchURL(ctx context.Context, me *state.Session, args []byte) string
- func (s OSCARProxy) GetDirURL(ctx context.Context, me *state.Session, args []byte) string
- func (s OSCARProxy) GetInfoURL(ctx context.Context, me *state.Session, args []byte) string
- func (s OSCARProxy) GetStatus(ctx context.Context, me *state.Session, args []byte) string
- func (s OSCARProxy) IMIn(ctx context.Context, chatRegistry *ChatRegistry, ...) string
- func (s OSCARProxy) InitDone(ctx context.Context, sess *state.Session) string
- func (s OSCARProxy) NewServeMux() http.Handler
- func (s OSCARProxy) ProfileHandler(w http.ResponseWriter, r *http.Request)
- func (s OSCARProxy) RateLimiterMiddleware(next http.Handler) http.Handler
- func (s OSCARProxy) RecvBOS(ctx context.Context, me *state.Session, chatRegistry *ChatRegistry, ...) error
- func (s OSCARProxy) RecvChat(ctx context.Context, me *state.Session, chatID int, ch chan<- []byte)
- func (s OSCARProxy) RecvClientCmd(ctx context.Context, sessBOS *state.Session, chatRegistry *ChatRegistry, ...) (reply string)
- func (s OSCARProxy) RemoveBuddy(ctx context.Context, me *state.Session, args []byte) string
- func (s OSCARProxy) RvousAccept(ctx context.Context, me *state.Session, args []byte) string
- func (s OSCARProxy) RvousCancel(ctx context.Context, me *state.Session, args []byte) string
- func (s OSCARProxy) SendIM(ctx context.Context, sender *state.Session, args []byte) string
- func (s OSCARProxy) SetAway(ctx context.Context, me *state.Session, args []byte) string
- func (s OSCARProxy) SetCaps(ctx context.Context, me *state.Session, args []byte) string
- func (s OSCARProxy) SetConfig(ctx context.Context, me *state.Session, args []byte) string
- func (s OSCARProxy) SetDir(ctx context.Context, me *state.Session, args []byte) string
- func (s OSCARProxy) SetIdle(ctx context.Context, me *state.Session, args []byte) string
- func (s OSCARProxy) SetInfo(ctx context.Context, me *state.Session, args []byte) string
- func (s OSCARProxy) Signon(ctx context.Context, args []byte) (*state.Session, []string)
- func (s OSCARProxy) Signout(ctx context.Context, me *state.Session, chatRegistry *ChatRegistry)
- func (s OSCARProxy) UpdateBuddyArrival(snac wire.SNAC_0x03_0x0B_BuddyArrived) string
- func (s OSCARProxy) UpdateBuddyDeparted(snac wire.SNAC_0x03_0x0C_BuddyDeparted) string
- type OServiceService
- type PermitDenyService
- type Server
- type TOCConfigStore
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type AdminService ¶ added in v0.16.0
type AuthService ¶
type AuthService interface { BUCPChallenge(ctx context.Context, bodyIn wire.SNAC_0x17_0x06_BUCPChallengeRequest, newUUID func() uuid.UUID) (wire.SNACMessage, error) BUCPLogin(ctx context.Context, bodyIn wire.SNAC_0x17_0x02_BUCPLoginRequest, newUserFn func(screenName state.DisplayScreenName) (state.User, error), advertisedHost string) (wire.SNACMessage, error) CrackCookie(authCookie []byte) (state.ServerCookie, error) FLAPLogin(ctx context.Context, frame wire.FLAPSignonFrame, newUserFn func(screenName state.DisplayScreenName) (state.User, error), here string) (wire.TLVRestBlock, error) RegisterBOSSession(ctx context.Context, authCookie state.ServerCookie) (*state.Session, error) RegisterChatSession(ctx context.Context, authCookie state.ServerCookie) (*state.Session, error) RetrieveBOSSession(ctx context.Context, authCookie state.ServerCookie) (*state.Session, error) Signout(ctx context.Context, sess *state.Session) SignoutChat(ctx context.Context, sess *state.Session) }
type BuddyListRegistry ¶
type BuddyListRegistry interface { RegisterBuddyList(ctx context.Context, user state.IdentScreenName) error UnregisterBuddyList(ctx context.Context, user state.IdentScreenName) error }
BuddyListRegistry is the interface for keeping track of users with active buddy lists. Once registered, a user becomes visible to other users' buddy lists and vice versa.
type BuddyService ¶
type BuddyService interface { AddBuddies(ctx context.Context, sess *state.Session, inBody wire.SNAC_0x03_0x04_BuddyAddBuddies) error BroadcastBuddyDeparted(ctx context.Context, sess *state.Session) error DelBuddies(ctx context.Context, sess *state.Session, inBody wire.SNAC_0x03_0x05_BuddyDelBuddies) error RightsQuery(ctx context.Context, inFrame wire.SNACFrame) wire.SNACMessage }
type ChatNavService ¶
type ChatNavService interface {}
type ChatRegistry ¶
type ChatRegistry struct {
// contains filtered or unexported fields
}
ChatRegistry manages the chat rooms that a user is connected to during a TOC session. It maintains mappings between chat room identifiers, metadata, and active chat sessions.
This struct provides thread-safe operations for adding, retrieving, and managing chat room metadata and associated sessions.
func NewChatRegistry ¶
func NewChatRegistry() *ChatRegistry
NewChatRegistry creates a new ChatRegistry instances.
func (*ChatRegistry) Add ¶
func (c *ChatRegistry) Add(room wire.ICBMRoomInfo) int
Add registers metadata for a newly joined chat room and returns a unique identifier for it. If the room is already registered, it returns the existing ID.
func (*ChatRegistry) LookupRoom ¶
func (c *ChatRegistry) LookupRoom(chatID int) (wire.ICBMRoomInfo, bool)
LookupRoom retrieves metadata for the chat room registered with chatID. It returns the room metadata and a boolean indicating whether the chat ID was found.
func (*ChatRegistry) RegisterSess ¶
func (c *ChatRegistry) RegisterSess(chatID int, sess *state.Session)
RegisterSess associates a chat session with a chat room. If a session is already registered for the given chat ID, it will be overwritten.
func (*ChatRegistry) RemoveSess ¶ added in v0.15.3
func (c *ChatRegistry) RemoveSess(chatID int)
RemoveSess removes a chat session.
func (*ChatRegistry) RetrieveSess ¶
func (c *ChatRegistry) RetrieveSess(chatID int) *state.Session
RetrieveSess retrieves the chat session associated with the given chat ID. If no session is registered for the chat ID, it returns nil.
func (*ChatRegistry) Sessions ¶ added in v0.15.3
func (c *ChatRegistry) Sessions() []*state.Session
Sessions retrieves all the chat sessions.
type ChatService ¶
type CookieBaker ¶
type CookieBaker interface { // Crack verifies and decodes a previously issued authentication token. // Returns the original payload if the token is valid. Crack(data []byte) ([]byte, error) // Issue creates a new authentication token from the given payload. // The resulting token can later be verified using Crack. Issue(data []byte) ([]byte, error) }
CookieBaker defines methods for issuing and verifying AIM authentication tokens ("cookies"). These tokens are used for authenticating client sessions with AIM services.
type DirSearchService ¶
type DirSearchService interface {
InfoQuery(_ context.Context, inFrame wire.SNACFrame, inBody wire.SNAC_0x0F_0x02_InfoQuery) (wire.SNACMessage, error)
}
type ICBMService ¶
type ICBMService interface { ChannelMsgToHost(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, inBody wire.SNAC_0x04_0x06_ICBMChannelMsgToHost) (*wire.SNACMessage, error) ClientEvent(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, inBody wire.SNAC_0x04_0x14_ICBMClientEvent) error EvilRequest(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, inBody wire.SNAC_0x04_0x08_ICBMEvilRequest) (wire.SNACMessage, error) ParameterQuery(ctx context.Context, inFrame wire.SNACFrame) wire.SNACMessage ClientErr(ctx context.Context, sess *state.Session, frame wire.SNACFrame, body wire.SNAC_0x04_0x0B_ICBMClientErr) error }
type IPRateLimiter ¶ added in v0.17.0
type IPRateLimiter struct {
// contains filtered or unexported fields
}
IPRateLimiter provides per-IP rate limiting using a token bucket algorithm. It caches individual rate limiters per IP address with automatic TTL expiration.
func NewIPRateLimiter ¶ added in v0.17.0
NewIPRateLimiter returns a new IPRateLimiter that limits each IP to the specified rate and burst, with limiter state expiring after the given TTL. Entries are retained for up to 2×TTL to reduce churn under frequent lookups.
func (*IPRateLimiter) Allow ¶ added in v0.17.0
func (l *IPRateLimiter) Allow(ip string) (allowed bool)
Allow returns true if the request from the given IP is allowed under its rate limit. If no limiter exists for the IP, one is created and tracked in the cache.
type LocateService ¶
type LocateService interface { SetDirInfo(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, inBody wire.SNAC_0x02_0x09_LocateSetDirInfo) (wire.SNACMessage, error) SetInfo(ctx context.Context, sess *state.Session, inBody wire.SNAC_0x02_0x04_LocateSetInfo) error UserInfoQuery(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, inBody wire.SNAC_0x02_0x05_LocateUserInfoQuery) (wire.SNACMessage, error) DirInfo(ctx context.Context, inFrame wire.SNACFrame, body wire.SNAC_0x02_0x0B_LocateGetDirInfo) (wire.SNACMessage, error) }
type OSCARProxy ¶
type OSCARProxy struct { AdminService AdminService AuthService AuthService BuddyListRegistry BuddyListRegistry BuddyService BuddyService ChatService ChatService CookieBaker CookieBaker DirSearchService DirSearchService ICBMService ICBMService LocateService LocateService Logger *slog.Logger OServiceService OServiceService PermitDenyService PermitDenyService TOCConfigStore TOCConfigStore SNACRateLimits wire.SNACRateLimits HTTPIPRateLimiter *IPRateLimiter }
OSCARProxy acts as a bridge between TOC clients and the OSCAR server, translating protocol messages between the two.
It performs the following functions:
- Receives TOC messages from the client, converts them into SNAC messages, and forwards them to the OSCAR server. The SNAC response is then converted back into a TOC response for the client.
- Receives incoming messages from the OSCAR server and translates them into TOC responses for the client.
func (OSCARProxy) AddBuddy ¶
AddBuddy handles the toc_add_buddy TOC command.
From the TiK documentation:
Add buddies to your buddy list. This does not change your saved config.
Command syntax: toc_add_buddy <Buddy User 1> [<Buddy User2> [<Buddy User 3> [...]]]
func (OSCARProxy) AddDeny ¶
AddDeny handles the toc_add_deny TOC command.
From the TiK documentation:
ADD the following people to your deny mode. If you are in permit mode it will switch you to deny mode first. With no arguments and in permit mode, this will switch you to deny none. If already in deny mode, no arguments does nothing and your deny list remains unchanged.
Command syntax: toc_add_deny [ <User 1> [<User 2> [...]]]
func (OSCARProxy) AddPermit ¶
AddPermit handles the toc_add_permit TOC command.
From the TiK documentation:
ADD the following people to your permit mode. If you are in deny mode it will switch you to permit mode first. With no arguments and in deny mode this will switch you to permit none. If already in permit mode, no arguments does nothing and your permit list remains the same.
Command syntax: toc_add_permit [ <User 1> [<User 2> [...]]]
func (OSCARProxy) AuthMiddleware ¶
func (s OSCARProxy) AuthMiddleware(next http.Handler) http.Handler
AuthMiddleware is an HTTP middleware that enforces authentication using an authorization cookie provided as a query parameter. It validates and decrypts the cookie before allowing the request to proceed.
If the `cookie` query parameter is missing or invalid, the middleware responds with an appropriate HTTP error:
- 400 Bad Request if the `cookie` parameter is missing.
- 403 Forbidden if the cookie is invalid or cannot be decrypted.
Requests with a valid cookie are passed to the next handler.
func (OSCARProxy) ChangePassword ¶ added in v0.16.0
ChangePassword handles the toc_change_passwd TOC command.
From the TiK documentation:
Change a user's password. An ADMIN_PASSWD_STATUS or ERROR message will be sent back to the client.
Command syntax: toc_change_passwd <existing_passwd> <new_passwd>
func (OSCARProxy) ChatAccept ¶
func (s OSCARProxy) ChatAccept( ctx context.Context, me *state.Session, chatRegistry *ChatRegistry, args []byte, ) (int, string)
ChatAccept handles the toc_chat_accept TOC command.
From the TiK documentation:
Accept a CHAT_INVITE message from TOC. The server will send a CHAT_JOIN in response.
Command syntax: toc_chat_accept <Chat Room ID>
func (OSCARProxy) ChatIn ¶
func (s OSCARProxy) ChatIn(ctx context.Context, snac wire.SNAC_0x0E_0x06_ChatChannelMsgToClient, chatID int) string
ChatIn handles the CHAT_IN TOC command.
From the TiK documentation:
A chat message was sent in a chat room.
Command syntax: CHAT_IN:<Chat Room Id>:<Source User>:<Whisper? T/F>:<Message>
func (OSCARProxy) ChatInvite ¶
func (s OSCARProxy) ChatInvite(ctx context.Context, me *state.Session, chatRegistry *ChatRegistry, args []byte) string
ChatInvite handles the toc_chat_invite TOC command.
From the TiK documentation:
Once you are inside a chat room you can invite other people into that room. Remember to quote and encode the invite message.
Command syntax: toc_chat_invite <Chat Room ID> <Invite Msg> <buddy1> [<buddy2> [<buddy3> [...]]]
func (OSCARProxy) ChatJoin ¶
func (s OSCARProxy) ChatJoin( ctx context.Context, me *state.Session, chatRegistry *ChatRegistry, args []byte, ) (int, string)
ChatJoin handles the toc_chat_join TOC command.
From the TiK documentation:
Join a chat room in the given exchange. Exchange is an integer that represents a group of chat rooms. Different exchanges have different properties. For example some exchanges might have room replication (ie a room never fills up, there are just multiple instances.) and some exchanges might have navigational information. Currently, exchange should always be 4, however this may change in the future. You will either receive an ERROR if the room couldn't be joined or a CHAT_JOIN message. The Chat Room Name is case-insensitive and consecutive spaces are removed.
Command syntax: toc_chat_join <Exchange> <Chat Room Name>
func (OSCARProxy) ChatLeave ¶
func (s OSCARProxy) ChatLeave(ctx context.Context, chatRegistry *ChatRegistry, args []byte) string
ChatLeave handles the toc_chat_leave TOC command.
From the TiK documentation:
Leave the chat room.
Command syntax: toc_chat_leave <Chat Room ID>
func (OSCARProxy) ChatSend ¶
func (s OSCARProxy) ChatSend(ctx context.Context, chatRegistry *ChatRegistry, args []byte) string
ChatSend handles the toc_chat_send TOC command.
From the TiK documentation:
Send a message in a chat room using the chat room id from CHAT_JOIN. Since reflection is always on in TOC, you do not need to add the message to your chat UI, since you will get a CHAT_IN with the message. Remember to quote and encode the message.
Command syntax: toc_chat_send <Chat Room ID> <Message>
func (OSCARProxy) ChatUpdateBuddyArrived ¶
func (s OSCARProxy) ChatUpdateBuddyArrived(snac wire.SNAC_0x0E_0x03_ChatUsersJoined, chatID int) string
ChatUpdateBuddyArrived handles the CHAT_UPDATE_BUDDY TOC command for chat room arrival events.
From the TiK documentation:
This one command handles arrival/departs from a chat room. The very first message of this type for each chat room contains the users already in the room.
Command syntax: CHAT_UPDATE_BUDDY:<Chat Room Id>:<Inside? T/F>:<User 1>:<User 2>...
func (OSCARProxy) ChatUpdateBuddyLeft ¶
func (s OSCARProxy) ChatUpdateBuddyLeft(snac wire.SNAC_0x0E_0x04_ChatUsersLeft, chatID int) string
ChatUpdateBuddyLeft handles the CHAT_UPDATE_BUDDY TOC command for chat room departure events.
From the TiK documentation:
This one command handles arrival/departs from a chat room. The very first message of this type for each chat room contains the users already in the room.
Command syntax: CHAT_UPDATE_BUDDY:<Chat Room Id>:<Inside? T/F>:<User 1>:<User 2>...
func (OSCARProxy) ChatWhisper ¶ added in v0.16.0
func (s OSCARProxy) ChatWhisper(ctx context.Context, chatRegistry *ChatRegistry, args []byte) string
ChatWhisper handles the toc_chat_send TOC command.
From the TiK documentation:
Send a message in a chat room using the chat room id from CHAT_JOIN. This message is directed at only one person. (Currently you DO need to add this to your UI.) Remember to quote and encode the message. Chat whispering is different from IMs since it is linked to a chat room, and should usually be displayed in the chat room UI.
Command syntax: toc_chat_whisper <Chat Room ID> <dst_user> <Message>
func (OSCARProxy) DirInfoHandler ¶
func (s OSCARProxy) DirInfoHandler(w http.ResponseWriter, request *http.Request)
DirInfoHandler handles requests to retrieve directory information for a user. It queries the LocateService to fetch directory details associated with the given screen name.
The request must include the following query parameter:
- `user`: The screen name of the user whose directory info is being requested.
If the `user` parameter is missing, it responds with a 400 Bad Request. If no directory information is found, it responds with a 404 Not Found.
func (OSCARProxy) DirSearchHandler ¶
func (s OSCARProxy) DirSearchHandler(w http.ResponseWriter, r *http.Request)
DirSearchHandler handles requests to perform a directory search based on various criteria. It queries the DirSearchService to find users matching the specified parameters. There are 3 search modes: name, email, keyword.
-Named-based search is toggled by the presence of either `first_name` and/or `last_name` params. The following search params can be passed: -`first_name` -`middle_name` -`last_name` -`maiden_name` -`city` -`state` -`country` -Email-based search is triggered by the`email` param. -Keyword-based search is triggered by the `keyword` param.
If the search is missing required name parameters, it responds with a 400 Bad Request.
func (OSCARProxy) Evil ¶
Evil handles the toc_evil TOC command.
From the TiK documentation:
Evil/Warn someone else. The 2nd argument is either the string "norm" for a normal warning, or "anon" for an anonymous warning. You can only evil people who have recently sent you ims. The higher someones evil level, the slower they can send message.
Command syntax: toc_evil <User> <norm|anon>
func (OSCARProxy) Eviled ¶
func (s OSCARProxy) Eviled(snac wire.SNAC_0x01_0x10_OServiceEvilNotification) string
Eviled handles the EVILED TOC command.
From the TiK documentation:
The user was just eviled.
Command syntax: EVILED:<new evil>:<name of eviler, blank if anonymous>
func (OSCARProxy) FormatNickname ¶ added in v0.16.0
FormatNickname handles the toc_format_nickname TOC command.
From the TiK documentation:
Reformat a user's nickname. An ADMIN_NICK_STATUS or ERROR message will be sent back to the client.
Command syntax: toc_format_nickname <new_format>
func (OSCARProxy) GetDirSearchURL ¶
GetDirSearchURL handles the toc_dir_search TOC command.
From the TiK documentation:
Perform a search of the Oscar Directory, using colon separated fields as in: "first name":"middle name":"last name":"maiden name":"city":"state":"country":"email"
You can search by keyword by setting search terms in the 11th position (this feature is not in the TiK docs but is present in the code):
::::::::::"search kw" Returns either a GOTO_URL or ERROR msg.
Command syntax: toc_dir_search <info information>
func (OSCARProxy) GetDirURL ¶
GetDirURL handles the toc_get_dir TOC command.
From the TiK documentation:
Gets a user's dir info a GOTO_URL or ERROR message will be sent back to the client.
Command syntax: toc_get_dir <username>
func (OSCARProxy) GetInfoURL ¶
GetInfoURL handles the toc_get_info TOC command.
From the TiK documentation:
Gets a user's info a GOTO_URL or ERROR message will be sent back to the client.
Command syntax: toc_get_info <username>
func (OSCARProxy) GetStatus ¶ added in v0.16.0
GetStatus handles the toc_get_status TOC command.
From the TOC2 documentation:
This useful command wasn't ever really documented. It returns either an UPDATE_BUDDY message or an ERROR message depending on whether or not the guy appears to be online.
Command syntax: toc_get_status <screenname>
func (OSCARProxy) IMIn ¶
func (s OSCARProxy) IMIn(ctx context.Context, chatRegistry *ChatRegistry, snac wire.SNAC_0x04_0x07_ICBMChannelMsgToClient) string
IMIn handles the IM_IN TOC command.
From the TiK documentation:
Receive an IM from someone. Everything after the third colon is the incoming message, including other colons.
Command syntax: IM_IN:<Source User>:<Auto Response T/F?>:<Message>
func (OSCARProxy) InitDone ¶
InitDone handles the toc_init_done TOC command.
From the TiK documentation:
Tells TOC that we are ready to go online. TOC clients should first send TOC the buddy list and any permit/deny lists. However, toc_init_done must be called within 30 seconds after toc_signon, or the connection will be dropped. Remember, it can't be called until after the SIGN_ON message is received. Calling this before or multiple times after a SIGN_ON will cause the connection to be dropped.
Note: The business logic described in the last 3 sentences are not yet implemented.
Command syntax: toc_init_done
func (OSCARProxy) NewServeMux ¶
func (s OSCARProxy) NewServeMux() http.Handler
NewServeMux creates and returns an HTTP mux that serves all TOC routes.
func (OSCARProxy) ProfileHandler ¶
func (s OSCARProxy) ProfileHandler(w http.ResponseWriter, r *http.Request)
ProfileHandler handles requests to retrieve a user's profile information. It queries the LocateService to fetch profile data for the specified user.
The request must include the following query parameters:
- `from`: The screen name of the user making the request.
- `user`: The screen name of the user whose profile is being requested.
If any required parameter is missing, it responds with a 400 Bad Request. If the requested user is unavailable, it responds with a 404 Not Found.
func (OSCARProxy) RateLimiterMiddleware ¶ added in v0.17.0
func (s OSCARProxy) RateLimiterMiddleware(next http.Handler) http.Handler
func (OSCARProxy) RecvBOS ¶
func (s OSCARProxy) RecvBOS(ctx context.Context, me *state.Session, chatRegistry *ChatRegistry, ch chan<- []byte) error
RecvBOS routes incoming SNAC messages from the BOS server to their corresponding TOC handlers. It ignores any SNAC messages for which there is no TOC response.
func (OSCARProxy) RecvChat ¶
RecvChat routes incoming SNAC messages from the chat server to their corresponding TOC handlers. It ignores any SNAC messages for which there is no TOC response.
func (OSCARProxy) RecvClientCmd ¶
func (s OSCARProxy) RecvClientCmd( ctx context.Context, sessBOS *state.Session, chatRegistry *ChatRegistry, payload []byte, toCh chan<- []byte, doAsync func(f func() error), ) (reply string)
RecvClientCmd processes a client TOC command and returns a server reply.
* sessBOS is the current user's session. * chatRegistry manages the current user's chat sessions * payload is the command + arguments * toCh is the channel that transports messages to client * doAsync performs async tasks, is auto-cleaned up by caller
It returns true if the server can continue processing commands.
func (OSCARProxy) RemoveBuddy ¶
RemoveBuddy handles the toc_remove_buddy TOC command.
From the TiK documentation:
Remove buddies from your buddy list. This does not change your saved config.
Command syntax: toc_remove_buddy <Buddy User 1> [<Buddy User2> [<Buddy User 3> [...]]]
func (OSCARProxy) RvousAccept ¶ added in v0.16.0
RvousAccept handles the toc_rvous_accept TOC command.
From the TiK documentation:
Accept a rendezvous proposal from the user <nick>. <cookie> is the cookie from the RVOUS_PROPOSE message. <service> is the UUID the proposal was for. <tlvlist> contains a list of tlv tags followed by base64 encoded values.
Note: This method does not actually process the TLV list param, as it's not passed in the TiK client, the reference implementation.
Command syntax: toc_rvous_accept <nick> <cookie> <service>
func (OSCARProxy) RvousCancel ¶ added in v0.16.0
RvousCancel handles the toc_rvous_cancel TOC command.
From the TiK documentation:
Cancel a rendezvous proposal from the user <nick>. <cookie> is the cookie from the RVOUS_PROPOSE message. <service> is the UUID the proposal was for. <tlvlist> contains a list of tlv tags followed by base64 encoded values.
Note: This method does not actually process the TLV list param, as it's not passed in the TiK client, the reference implementation.
Command syntax: toc_rvous_cancel <nick> <cookie> <service>
func (OSCARProxy) SendIM ¶
SendIM handles the toc_send_im TOC command.
From the TiK documentation:
Send a message to a remote user. Remember to quote and encode the message. If the optional string "auto" is the last argument, then the auto response flag will be turned on for the IM.
Command syntax: toc_send_im <Destination User> <Message> [auto]
func (OSCARProxy) SetAway ¶
SetAway handles the toc_chat_join TOC command.
From the TiK documentation:
If the away message is present, then the unavailable status flag is set for the user. If the away message is not present, then the unavailable status flag is unset. The away message is basic HTML, remember to encode the information.
Command syntax: toc_set_away [<away message>]
func (OSCARProxy) SetCaps ¶
SetCaps handles the toc_set_caps TOC command.
From the TiK documentation:
Set my capabilities. All capabilities that we support need to be sent at the same time. Capabilities are represented by UUIDs.
This method automatically adds the "chat" capability since it doesn't seem to be sent explicitly by the official clients, even though they support chat.
Command syntax: toc_set_caps [ <Capability 1> [<Capability 2> [...]]]
func (OSCARProxy) SetConfig ¶
SetConfig handles the toc_set_config TOC command.
From the TiK documentation:
Set the config information for this user. The config information is line oriented with the first character being the item type, followed by a space, with the rest of the line being the item value. Only letters, numbers, and spaces should be used. Remember you will have to enclose the entire config in quotes. Item Types: - g - Buddy Group (All Buddies until the next g or the end of config are in this group.) - b - A Buddy - p - Person on permit list - d - Person on deny list - m - Permit/Deny Mode. Possible values are - 1 - Permit All - 2 - Deny All - 3 - Permit Some - 4 - Deny Some
This method doesn't attempt to validate any of the configuration--it saves the config as received from the client.
Command syntax: toc_set_config <Config Info>
func (OSCARProxy) SetDir ¶
SetDir handles the toc_set_dir TOC command.
From the TiK documentation:
Set the DIR user information. This is a colon separated fields as in: "first name":"middle name":"last name":"maiden name":"city":"state":"country":"email":"allow web searches". Should return a DIR_STATUS msg. Having anything in the "allow web searches" field allows people to use web-searches to find your directory info. Otherwise, they'd have to use the client.
The fields "email" and "allow web searches" are ignored by this method.
Command syntax: toc_set_dir <info information>
func (OSCARProxy) SetIdle ¶
SetIdle handles the toc_set_idle TOC command.
From the TiK documentation:
Set idle information. If <idle secs> is 0 then the user isn't idle at all. If <idle secs> is greater than 0 then the user has already been idle for <idle secs> number of seconds. The server will automatically keep incrementing this number, so do not repeatedly call with new idle times.
Command syntax: toc_set_idle <idle secs>
func (OSCARProxy) SetInfo ¶
SetInfo handles the toc_set_info TOC command.
From the TiK documentation:
Set the LOCATE user information. This is basic HTML. Remember to encode the info.
Command syntax: toc_set_info <info information>
func (OSCARProxy) Signon ¶
Signon handles the toc_signon TOC command.
From the TiK documentation:
The password needs to be roasted with the Roasting String if coming over a FLAP connection, CP connections don't use roasted passwords. The language specified will be used when generating web pages, such as the get info pages. Currently, the only supported language is "english". If the language sent isn't found, the default "english" language will be used. The version string will be used for the client identity, and must be less than 50 characters. Passwords are roasted when sent to the host. This is done so they aren't sent in "clear text" over the wire, although they are still trivial to decode. Roasting is performed by first xoring each byte in the password with the equivalent modulo byte in the roasting string. The result is then converted to ascii hex, and prepended with "0x". So for example the password "password" roasts to "0x2408105c23001130". The Roasting String is Tic/Toc.
Command syntax: toc_signon <authorizer host> <authorizer port> <User Name> <Password> <language> <version>
func (OSCARProxy) Signout ¶
func (s OSCARProxy) Signout(ctx context.Context, me *state.Session, chatRegistry *ChatRegistry)
Signout terminates a TOC session. It sends departure notifications to buddies, de-registers buddy list and session.
func (OSCARProxy) UpdateBuddyArrival ¶
func (s OSCARProxy) UpdateBuddyArrival(snac wire.SNAC_0x03_0x0B_BuddyArrived) string
UpdateBuddyArrival handles the UPDATE_BUDDY TOC command for buddy arrival events.
From the TiK documentation:
This one command handles arrival/depart/updates. Evil Amount is a percentage, Signon Time is UNIX epoc, idle time is in minutes, UC (User Class) is a two/three character string. - uc[0] - ' ' - Ignore - 'A' - On AOL - uc[1] - ' ' - Ignore - 'A' - Oscar Admin - 'U' - Oscar Unconfirmed - 'O' - Oscar Normal - uc[2] - '\0' - Ignore - ' ' - Ignore - 'U' - The user has set their unavailable flag.
Command syntax: UPDATE_BUDDY:<Buddy User>:<Online? T/F>:<Evil Amount>:<Signon Time>:<IdleTime>:<UC>
func (OSCARProxy) UpdateBuddyDeparted ¶
func (s OSCARProxy) UpdateBuddyDeparted(snac wire.SNAC_0x03_0x0C_BuddyDeparted) string
UpdateBuddyDeparted handles the UPDATE_BUDDY TOC command for buddy departure events.
From the TiK documentation:
This one command handles arrival/depart/updates. Evil Amount is a percentage, Signon Time is UNIX epoc, idle time is in minutes, UC (User Class) is a two/three character string. - uc[0] - ' ' - Ignore - 'A' - On AOL - uc[1] - ' ' - Ignore - 'A' - Oscar Admin - 'U' - Oscar Unconfirmed - 'O' - Oscar Normal - uc[2] - '\0' - Ignore - ' ' - Ignore - 'U' - The user has set their unavailable flag.
Command syntax: UPDATE_BUDDY:<Buddy User>:<Online? T/F>:<Evil Amount>:<Signon Time>:<IdleTime>:<UC>
type OServiceService ¶
type OServiceService interface { ClientOnline(ctx context.Context, service uint16, bodyIn wire.SNAC_0x01_0x02_OServiceClientOnline, sess *state.Session) error IdleNotification(ctx context.Context, sess *state.Session, bodyIn wire.SNAC_0x01_0x11_OServiceIdleNotification) error ServiceRequest(ctx context.Context, service uint16, sess *state.Session, frame wire.SNACFrame, bodyIn wire.SNAC_0x01_0x04_OServiceServiceRequest, listener config.Listener) (wire.SNACMessage, error) }
type PermitDenyService ¶
type PermitDenyService interface { AddDenyListEntries(ctx context.Context, sess *state.Session, body wire.SNAC_0x09_0x07_PermitDenyAddDenyListEntries) error AddPermListEntries(ctx context.Context, sess *state.Session, body wire.SNAC_0x09_0x05_PermitDenyAddPermListEntries) error DelDenyListEntries(ctx context.Context, sess *state.Session, body wire.SNAC_0x09_0x08_PermitDenyDelDenyListEntries) error DelPermListEntries(ctx context.Context, sess *state.Session, body wire.SNAC_0x09_0x06_PermitDenyDelPermListEntries) error RightsQuery(_ context.Context, frame wire.SNACFrame) wire.SNACMessage }
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
Server implements a TOC protocol server that multiplexes TOC/HTTP and TOC/FLAP requests. It acts as a gateway, forwarding all TOC requests to the OSCAR server for processing.
func NewServer ¶ added in v0.19.0
func NewServer(listenerCfg []string, logger *slog.Logger, BOSProxy OSCARProxy, ipRateLimiter *IPRateLimiter) *Server
func (*Server) ListenAndServe ¶ added in v0.19.0
type TOCConfigStore ¶
type TOCConfigStore interface { // SetTOCConfig sets the user's TOC config. The TOC config is the server-side // buddy list functionality for TOC. This configuration is not available to // OSCAR clients. SetTOCConfig(ctx context.Context, user state.IdentScreenName, config string) error User(ctx context.Context, screenName state.IdentScreenName) (*state.User, error) }